Использование sed с параллельным доступом дает пустой вывод при перенаправлении в файл

Я использую zsh ракушка. Я пытаюсь использовать sed заменить некоторый текст во многих файлах, используя параллель для ускорения процесса. Когда я проверил это на одном файле и позволил выводу команды перейти к stdout Я увидел ожидаемый результат. Когда я попытался перенаправить этот вывод в файл, я получил пустой файл. В чем дело? Вот тривиальный пример использования одного файла данных, который вы можете вырезать и вставить для иллюстрации...

setopt interactivecomments
#  In this trivial example it is obviously non-sensical
#  to use parallel, but in reality I have many files...

#  Some very simple input data...
paste <(printf "%s\n" `seq 1 4`) <(printf "%s\n" `seq 1 4`) > ./input.txt
#  This looks like:
#1       1
#2       2
#3       3
#4       4


#  Pass data file to parallel and use sed to substitute.
#  e.g. want to replace line '3 3' with '3 33'
#  Output goes to stdout & seems correct...
z=`find ./input.txt`
echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/"'
#1       1
#2       2
#3       33    ===> correct replacement
#4       4

# But redirecting to a file leads to empty file...
echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/" > {//}/result.txt'

# Empty file
cat ./result.txt

Что дает? Я указываю что-то неправильно?

Я использую:

  • Ubuntu 12.04.4 LTS
  • GNU parallel 20130522
  • GNU sed version 4.2.1
  • zsh 4.3.17

1 ответ

Решение

При использовании перенаправления внутри команды для parallel, вы должны использовать {} поместить вход в нужное место, в качестве параметра для sed:

echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/" {} > {//}/result.txt'

Кроме того, если {//} (или любая другая строка замены), parallel не добавляет ввод в конце команды автоматически. (В этом случае это было бы неправильно в любом случае, как это было бы после перенаправления.)

По сути, код в вопросе работает

sed "s/(^3.*3\)/\13/" > ./result.txt

но это должно быть

sed "s/(^3.*3\)/\13/" ./input.txt > ./result.txt
Другие вопросы по тегам