Как вывести результат awk в файл - PullRequest
4 голосов
/ 24 января 2010

Я пытаюсь вывести результат 'awk' в файл в моем скрипте, но безуспешно. Использование «>» не работает, почему?

for a in $(find $OUPUT_DIR/ -maxdepth 1 -mindepth 1 -type d -printf "%P\n")
do
    echo $a is a directory
    awk -F, '{ if ($10 == '"$a"') print $0 }' $OUPUT_DIR/CDRNOutput_${CDR_DATE}.csv > $OUPUT_DIR/$a/CDR-${CDR_DATE}.csv
done 

Ответы [ 2 ]

6 голосов
/ 24 января 2010

Перенаправление вывода - это, как правило, особенность оболочки, с которой вы работаете, и, учитывая степень ее использования, я был бы очень удивлен, если бы вы обнаружили в ней ошибку: -)

Вы уверены, что не пытаетесь перенаправить саму awk, а не оболочку?

Что происходит, когда вы делаете:

echo 'hello' | awk '{print}' >qq.tmp

Обновление:

Если это ваш код, как указано, это потому, что $a не раскрывается вашим сценарием оболочки, так как команда awk находится в одинарных кавычках.

for a in $(find $OUPUT_DIR/ -maxdepth 1 -mindepth 1 -type d -printf "%P\n")
do
    echo $a is a directory
    awk -F, '{ if ($10 == '"$a"') print $0 }' $OUPUT_DIR/CDRNOutput_${CDR_DATE}.csv > $OUPUT_DIR/$a/CDR-${CDR_DATE}.csv
done

Я обычно передаю конкретные значения awk, используя опцию -v, что-то вроде (в вашем случае):

awk -F, -v a=$a '{ if ($10==a) print $0 }' ...

Затем переменные становятся первоклассными awk гражданами, не беспокоясь о том, кто делает расширение.


Дальнейшее обновление:

Я поддерживаю мой оригинальный совет. В выбранном методе определенно есть что-то странное.

В моем домашнем каталоге есть каталог XpVm (среди прочих), и я создал файл CDRNOutput_X.csv, содержащий одну строку:

1,2,3,4,5,6,7,8,9,XpVm,11

Когда я выполняю:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == '"$a"') {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

(я удалил каталоги, начиная с ., так как они вызывали другую проблему), я получаю следующий вывод:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
NO
Downloads is a directory
NO

что явно не то, что ожидается. Однако, когда я использую опцию -v для awk, как я изначально предлагал, команда:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, -v a=$a '{
        if ($10 == a) {
            print $0
        } else {
            print "NO"
        }
    }' ./CDRNOutput_X.csv
done

(единственное отличие - изменения a), я получаю:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
1,2,3,4,5,6,7,8,9,XpVm,11
Downloads is a directory
NO

что правильно.


Окончательное обновление (надеюсь):

Я думаю, что проблема решена. Я сейчас на другом компьютере (поэтому имена каталогов просто tmp и tmp2) и, когда я запускаю оригинальный скрипт:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == '"$a"') {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

с измененным CDRNOutput_X.csv, содержащим tmp вместо XpVm, я получаю:

tmp is a directory
NO
tmp2 is a directory
NO

Это потому, что awk оператор if видит как:

        if ($10 == tmp) {

(без кавычек, поскольку кавычки на самом деле вне строка awk, используемая для окружения имени каталога). Это будет проверять $10 на соответствие переменной awk, называемой tmp, а не фактической строке "tmp". Вам нужно убедиться, что кавычки внутри awk, например:

        if ($10 == "tmp") {

и вы можете сделать это с помощью следующего скрипта (изменилась только строка if):

#!/bin/bash
for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == "'"$a"'") {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

Обратите внимание, что двойные кавычки дублируются. Я по-прежнему держал двойные кавычки сразу около $a на случай, если кто-то совершил чудовищное преступление, создав файл с пробелом: -)

Запуск этого скрипта приводит к:

tmp is a directory
1,2,3,4,5,6,7,8,9,tmp,11
tmp2 is a directory
NO

именно к этому я и стремился.

Итак, в результате, если вы не хотите использовать awk переменные, вы можете просто изменить строку awk с:

'{ if ($10 == '"$a"') print $0 }'

до:

'{ if ($10 == "'"$a"'") print $0 }'

и все должно работать нормально.

0 голосов
/ 24 января 2010

, так как у вас есть команда find с -mindepth и maxdepth, установленными в 1, вы можете просто сделать это с помощью оболочки

#!/bin/bash
CDR_DATE="somedate"
infile=CDRNOutput_${CDR_DATE}.csv
outfile=CDR-${CDR_DATE}.csv
OUPUT_DIR="/some/dir"
cd $OUPUT_DIR
for dir in */
do
    echo "${dir%/*} is a directory"
    dir=${dir%/*}
    while read -r a b c d e f g h i j k
    do
        case "$j" in
            $dir) echo $a $b $c $d $e $f $g $h $i $j $k >> $dir/$outfile;;
        esac
    done < $infile
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...