Должно быть отказоустойчиво, если вы выполняете CD в скрипте. Вы можете выполнить команду в неправильном каталоге, если вы этого не сделаете.
В вашей попытке вывод будет таким же, даже без цикла for, поскольку for file in home/TESTING
только передает home/TESTING
в качестве аргумента for
, поэтому он запускается только один раз. В случае
for file in home/TESTING/*
это могло бы случиться иначе как.
Я использовал find без --maxdepth
, поэтому он будет искать также все подкаталоги для файлов *.txt
. Если вы хотите, чтобы только текущий каталог $(find /home/TESTING/* -type f -name "*.txt")
мог быть заменен на $(ls *.txt)
, пока у вас нет каталога, оканчивающегося на .txt
, проблем не будет.
#!/bin/bash
# try cd to directory, do things upon success.
if cd /home/TESTING ;then
# set sequence number
let "x = 1"
# pass every file to for that find matching, sub directories will be also as there is no maxdeapth.
for file in $(find /home/TESTING/* -type f -name "*.txt") ; do
# print sequence number, and base file name, processed by variable substitution.
# basename can be used as well but this is bash built in.
echo "${x}${file##*/}"
# print file content, and put sequence number before each line with stream editor.
sed 's#^#'"${x}"'#g' ${file}
# increase sequence number with one.
let "x++"
done
# unset sequence number
unset 'x'
else
# print error on stderr
echo 'cd to /home/TESTING directory is failed' >&2
fi
Замена переменной:
Более того, я выбрал только эти 4, поскольку они похожи.
${var#pattern}
- Использовать значение var после удаления текста, соответствующего шаблону слева
${var##pattern}
- То же, что и выше, но вместо самого короткого удаляется самый длинный соответствующий элемент
${var%pattern}
- Использовать значение var после удаления текста, соответствующего шаблону справа
${var%%pattern}
- То же, что и выше, но вместо самого короткого удаляется самый длинный соответствующий элемент
Так что ${file##*/}
возьмет переменную $ file и сбросит каждый символ *
перед последним ##
косой чертой /
. Значение переменной $file
не может быть изменено, поэтому оно по-прежнему содержит путь и имя файла.
sed 's#^#'"${x}"'#g' ${file}
sed - это потоковый редактор, есть целые книги о его использовании, для этого конкретного. Обычно он помещается в одинарные кавычки, поэтому 's#^#1#g'
добавляет 1 начало каждой строки в файле. s
- это подстановка, ^
- начало файла, 1
- текст, g
- Глобальный, если вы не поместите туда данный первый мах, будет затронут.
#
- это разделитель, он может быть и другим, например, /
. Я блокирую одинарную кавычку, чтобы разрешить использование переменной, и снова открываю одинарную кавычку.
Если вы хотите заменить текст с .txt на .php, вы можете использовать sed 's#\.txt#\.php#g' file
, .
, имеющие специальное значение, он может заменить любой одиночный символ, поэтому его необходимо экранировать \
, чтобы использовать это как текст. иначе будет сопоставлено не только file.txt
, но и file1txt
.
Он может быть передан по конвейеру, вам не нужно указывать имя файла в этом случае, иначе вы должны указать хотя бы одно имя файла, в нашем случае это была переменная ${file}
, которая содержит имя файла. Как я уже упоминал, подстановка переменных не является изменением значения переменной, поэтому она по-прежнему содержит имя файла с путем.