2014-02-14 3 views
-2

Сценарий должен читать каждый файл в пути и заменять строку в каждой отдельной строке. Как создать файл temp и mv заменить, когда я повторяю 10 файлов входных файлов diff по тому же пути Pls советыНеобходима опция командной строки для оболочки Scripting -awk

SunOS 5,10

FILES=/export/home/*.txt 
for f in $FILES 
do 
echo "Processing $f file..." 
cat $f | awk 'BEGIN {FS="|"; OFS="|"} {$8=substr($8, 1, 6)"XXXXXXXXXX\""; print}' 
done 

входной файл

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"2455525445552000"|"1111-11-11"|75.00|"XXE11111"|"224425" 
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"2455525445552000"|"1111-11-11"|95.00|"VVE11111"|"224425" 

выходной файл

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"245552xxxxxxxxxx"|"1111-11-11"|75.00|"XXE11111"|"224425" 
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"245552xxxxxxxxxx"|"1111-11-11"|95.00|"VVE11111"|"224425" 

Не знаете, как использовать этот

cat $f | awk 'BEGIN {FS="|"; OFS="|"} {$8=substr($8, 1, 6)"XXXXXXXXXX\""; print}' $f > tmp.txt && mv tmp.txt $f 
+0

Когда вы делаете 'FILES =/export/home/*. Txt', вы фактически сохраняете шаблон glob, а не список имен файлов. Лучше либо не делать этого вообще, либо использовать оболочку, где вы можете сохранить результат в виде массива. –

+0

fedorqui-pls edit in better way Мне нужен ответ – Sen

+0

'cat | awk ... 'может быть гораздо лучше написано как' awk ... '. – twalberg

ответ

0

Чтобы достичь того, что, как представляется, ваш желаемый конечный результат вы можете использовать ред вместо AWK.

FILES=/export/home/*.txt 
for f in $FILES; do 
    echo "Processing ${f} file..." 
    ed "${f}" <<EOF 
% s/\([0-9]\{6\}\)[0-9]\{10\}/\1xxxxxxxxxx/ 
w 
q 
EOF 
done 

Для этого требуется меньшее количество шагов (например, командные вызовы), поскольку вы не создаете временный файл и не перемещаете его. Вместо этого вы редактируете файл на месте с требуемыми изменениями и затем закрываете его.

 
% means "operate on every line" (don't worry about lines that don't match) 
s means "perform a substitution" -- /[pattern]/[replacement]/ 
w means write 
q means quit 
EOF closes out the "here document" 

Надеюсь, что это поможет.

Edit Примечание: Charles Duffy указал, что ред $ {е} потерпит неудачу на имена файлов с пробелами в них и изд «$ {е}» не будет страдать от этого конкретного недостатка. Это правда. Также имеет место, однако, что цикл для цикла, вероятно, будет разбит на любые пробелы в именах файлов. Вы можете установить IFS ( IFS='\n'), чтобы обойти это ограничение на KSH, BASH, MKSH, ASH и DASH. В ZSH (в зависимости от вашей версии) вам может потребоваться установить SH_WORD_SPLIT. В качестве альтернативы можно изменить с для петли к петле в то время как с чтения:

FILES=/export/home/*.txt 
ls ${FILES} | while read f; do 
    echo "Processing ${f} file..." 
    ed "${f}" <<-EOF 
% s/\([0-9]\{6\}\)[0-9]\{10\}/\1xxxxxxxxxx/ 
w 
q 
EOF 
done 

Редактировать Примечание: Мои ошибочные утверждения выше пораженного но сохранили для исторических целей. См. Комментарии Чарльза Даффи (см. Ниже) для разъяснения.

+0

'ed" $ f "' - без кавычек это будет работать неправильно при именах файлов с пробелами. –

+0

@CharlesDuffy true. см. Редактирование примечания. Благодарю. –

+0

... ошибка.Использование 'ls' добавляет свои собственные, специфичные для платформы проблемы с нецензурными именами файлов и использует' read' без '-r' или очищенный' 'IFS' 'расширяет последовательности обратного слэша и очищает конечные пробелы. Гораздо безопаснее использовать 'printf '% s \ 0' $ FILES | в то время как IFS = '' read -r -d '' f', если по какой-то причине вы не смогли бы сделать правильную вещь и использовать 'for f in/export/home/*. txt' –

 Смежные вопросы

  • Нет связанных вопросов^_^