У меня есть следующая структура тематических папок:
./sub-CC0006/func
..
./sub-CC0199/func
В папке func у меня есть файл с именем sub-CC0006_ses-core2p2_task-loi3_run-01_events.tsv
. Когда я попытался поместить приведенный ниже код в цикл, это не сработало. (Я попытался сначала перейти к каждому каталогу темы, а затем изменить имена файлов .tsv на основе другого номера темы.)
awk -F"\t" -v OFS = "\t" '{
for (i=1;i<=NF;i++) {
if ($i == "NaN") $i = "n/a"
}
print $0
}' sub-CC0006_ses-core2p2_task-loi3_run-01_events.tsv > sub-CC0006_ses-core2p2_task-loi3_run-01_events_new.tsv &&
mv sub-CC0006_ses-core2p2_task-loi3_run-01_events_new.tsv sub-CC0006_ses-core2p2_task-loi3_run-01_events.tsv
Вот выдержка из одного из файлов, которыми я пытаюсь манипулировать:
Я только что отредактировал свой пост и включил его, спасибо за предложение. Еще немного контекста. Я просто пытаюсь изменить NaN во всех этих файлах на n/a. Однако у меня проблемы с циклом.
Можете ли вы опубликовать необработанный текст из файла, а не изображение?
Если я правильно понимаю вопрос, содержимое файлов в значительной степени не имеет значения для проблемы, о которой задается вопрос, которая заключается в управлении именами файлов, чтобы вывод awk
сохранялся где-то, а затем вывод перемещался/копировался поверх исходный файл. Сценарий awk
сопоставляет все вхождения NaN
в поле с n/a
, вот и все. Там нет волнения.
Базовый метод перезаписи файла отредактированной версией файла использует общее имя временного файла в качестве промежуточного файла.
Я предполагаю, что в каталоге sub-CC0199
подкаталог func
будет содержать sub-CC01999_ses-core2p2_task-loi3_run-01_events.tsv
и что любые другие файлы в каталоге следует игнорировать, и аналогично для каждого другого каталога. Сценарий становится проще, если вы просто хотите обработать все файлы (или все файлы *.tsv
, или какое-то другое соответствие шаблону) в каждом из подкаталогов func
для каждого из предметов.
tmpfile=$(mktemp "map.XXXXXX")
trap "rm -f $tmpfile; exit 1" 0 1 2 3 13 15
suffix = "_ses-core2p2_task-loi3_run-01_events.tsv"
for directory in sub-CC0???
do
file = "$directory/func/$directory$suffix"
if [ -f "$file" ]
then
awk '…' "$file" > "$tmpfile" &&
mv "$tmpfile" "$file"
fi
done
rm -f "$tmpfile" # Remove the temporary
trap 0 # Cancel the 'exit' trap; the script exits with status 0
Если вы беспокоитесь о сохранении ссылок (или прав собственности, или разрешений) на исходный файл или о том, что исходный файл может быть символической ссылкой, которую вы хотите сохранить, вы можете использовать cp "$tmpfile" "$file"; rm -f "$tmpfile"
вместо mv
. Однако это немного медленнее — но, если файлы не большие, вероятно, не измеримо медленнее.
Вы можете сгенерировать имя временного файла в цикле; это может быть немного безопаснее, если вы беспокоитесь о злоумышленниках. Файл является новым (ранее не существовало), когда он был создан mktemp
, но после того, как вы его переместили, злоумышленник может создать свою собственную символическую ссылку на что-то конфиденциальное, поэтому скрипт может неожиданно повредить другие файлы. (Вы также можете скопировать временный файл поверх оригинала, не удаляя временный, поэтому один и тот же файл используется для каждого файла .tsv
— вариантов множество.) Однако вы, вероятно, не работаете в такой враждебной среде.
Список ловушек предназначен для «ВЫХОДА» (0) и сигналов 1 (SIGHUP), 2 (SIGINT), 3 (SIGQUIT), 13 (SIGPIPE) и 15 (SIGTERM). Я научился писать сценарии, когда работали только числа — а они компактны. Если вы хотите быть немного более современным, вы можете перечислить короткие названия сигналов и условий:
trap "rm -f $tmpfile; exit 1" EXIT HUP INT QUIT PIPE TERM
…
trap EXIT
или (чтобы отменить несколько ловушек, хотя в этом нет необходимости, когда скрипт вот-вот выйдет):
trap - EXIT HUP INT QUIT PIPE TERM
Можете ли вы добавить выдержку из файла tsv для некоторого контекста?