INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Я хотів виконати другу команду ( head -1), тільки якщо перша команда успішна. Як я вдосконалюю цю команду?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Я хотів виконати другу команду ( head -1), тільки якщо перша команда успішна. Як я вдосконалюю цю команду?
Відповіді:
Спробуйте це:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Переходячи xargsдо -rпрапор змусить його працювати тільки , basenameякщо зчитує щонайменше один елемент зі стандартного вводу ( head -1).
head -1 запуститься, але ви не побачите і не захопите жодного результату з нього.
Крім того, якщо ви не хочете, щоб користувач бачив якісь помилки ls, ви можете перенаправити lsпотоковий stderr на /dev/null.
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Також зауважте, що я додав лапки навколо $MY_DIR. Таким чином, команда не вийде з ладу, якщо $MY_DIRмістить пробіли.
Якщо ви використовуєте сучасну оболонку, таку як bash, вам слід використовувати $( )оболонку захоплення замість задньої панелі. Вам слід також розглянути можливість зміни стилю змінних. Як правило, слід уникати використання великих імен змінних у сценаріях. Цей стиль, як правило, зарезервований для зарезервованих та екологічних змінних.
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basenameпрацює.
У трубопроводі всі команди запускаються та виконуються одночасно, а не одна за одною. Тож вам потрібно десь зберігати вихід.
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
Зауважте, що він передбачає, що імена файлів не містять символів нового рядка. Використання xargsтакож означатиме проблеми з порожніми символами, одинарними та подвійними лапки та зворотніми косою рисою. Залишення змінних без котирування означало б проблеми з простором, символами вкладки та символами підстановки. Забути --це означатиме проблеми з іменами файлів, починаючи з -.
Щоб отримати базове ім'я найстарішого файлу zshбез будь-якого з цих обмежень для символів (також уникає проблеми обмеженого розміру аргументів для команди):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Якщо збігу немає, ця команда не вдасться і скасувати сценарій. Ви також можете зробити:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
У такому випадку first_file_nameмасив буде містити 1 елемент, якщо є збіг, або 0, якщо ні. Потім ви можете зробити:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Знайдіть останній модифікований файл у каталозі:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
Використання: latest [directory/path/ [.extension]]
Замість того, щоб викликати basename, використовуйте розширення параметрів.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
У каталозі з цим вмістом:
foo.xml bar.xml baz.xml newest.xml
Вміст змінної base_fn був би: newest
Щоб правильно використовувати це для задоволення мети вашого запиту:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
EDIT: переглянувши питання, я зрозумів, що lsкоманда, про яку йдеться, шукає найдавніший файл у каталозі. цю ж функцію можна було б перейменовувати oldestі [[ $file -ot $oldest ]] && oldest=$fileзамість цього досягти того ж ефекту. вибачення за будь-яку плутанину.
Важливо зазначити, що ви абсолютно ні за яких обставин у людстві не повинні розбирати вихід лс. ніколи.
lsбазованим підходам, якщо є посилання, час модифікації цілі символьних посилань буде враховано (додайте -Lопцію, lsщоб отримати ту саму поведінку).
Я думаю, що найкращий варіант тут:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
якщо немає файлу, тоді код повернення ls дорівнює 2, але якщо він знайде якийсь файл, буде 0.
lsне підведе.