Использовать текущее имя файла ( "{}" ) несколько раз в "find -exec"?
Многие источники говорят, что каждый экземпляр {} будет заменен на имя файла, найденное через find, но когда я пытаюсь запустить следующее, я получаю только один текстовый файл, а его имя - ".txt"
find /directory -name "*pattern*" -exec cut -f8 {} > {}.txt \;
Цель заключалась в том, чтобы создать текстовый файл с только восьмым столбцом из каждого найденного файла, и каждый текстовый файл будет называться после его родительского файла. Что-то о том, что второй набор {} не заменяет имя файла для каждого найденного файла.
Ответы
Ответ 1
Попробуйте:
find /directory -name "*pattern*" -exec sh -c 'cut -f8 {} > {}.txt' \;
Но имейте в виду, что некоторые версии find требуют, чтобы {}
был отдельным аргументом, и не будет расширять {}
до имени файла в противном случае. Вы можете обойти это с помощью:
find /directory -name "*pattern*" -exec sh -c 'cut -f8 $0 > $0.txt' {} \;
(эта альтернативная команда поместит выходной файл в подкаталог, который содержит согласованный файл. При желании вы могли бы избежать этого, перенаправляя на ${0#*/}
Проблема в том, что find
не выполняет перенаправление, а оболочка. Ваша команда в точности эквивалентна:
# Sample of INCORRECT code
find /directory -name "*pattern*" -exec cut -f8 {} \; > {}.txt
Обратите внимание на следующее из стандарта:
<я > Если присутствует более одного аргумента, содержащего только два символа "{}" , поведение не указано.
Если строка имя_компьютера или аргумента содержит два символа "{}" , но не только два символа "{}" , это определяется реализацией, заменяет ли поиск эти два символа или использует строку без изменений.
Ответ 2
Чтобы справиться с оговорками, которые Уильям Пурселл упомянул в своем ответе, используйте следующее:
find /directory -name "*pattern*" -exec sh -c 'cut -f8 "$1" > "$1.txt"' x {} \;
Когда вы используете sh -c
, он получает позиционные параметры из аргументов, следующих за исполняемой строкой. Дополнительный x
заполняется $0
, а замещаемое имя файла станет $1
.
Двойные кавычки позволяют это правильно работать с именами файлов, содержащими пробелы и другие специальные символы.
Ответ 3
find /directory -name "*pattern*" | xargs awk '{z=FILENAME".txt";print $8>z}'