Linux for filename in

How to loop over files in directory and change path and add suffix to filename

I need to write a script that starts my program with different arguments. I start my program with: ./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt] . Here is the pseudocode for what I want to do:

for each filename in /Data do for int i = 0, i = 3, i++ ./MyProgram.exe Data/filename.txt Logs/filename_Log.txt end for end for 

How can I create the second argument from the first one, so it looks like dataABCD_Log1.txt and start my program?

@LéaGris The proposed duplicate seems less stellar, especially as one of the answers there still advocates looping over ls output. These seem different enough that I have not nominated that as a duplicate of this, either.

6 Answers 6

A couple of notes first: when you use Data/data1.txt as an argument, should it really be /Data/data1.txt (with a leading slash)? Also, should the outer loop scan only for .txt files, or all files in /Data? Here’s an answer, assuming /Data/data1.txt and .txt files only:

#!/bin/bash for filename in /Data/*.txt; do for ((i=0; i 
  • /Data/*.txt expands to the paths of the text files in /Data (including the /Data/ part)
  • $( . ) runs a shell command and inserts its output at that point in the command line
  • basename somepath .txt outputs the base part of somepath, with .txt removed from the end (e.g. /Data/file.txt -> file )

If you needed to run MyProgram with Data/file.txt instead of /Data/file.txt , use "$" to remove the leading slash. On the other hand, if it's really Data not /Data you want to scan, just use for filename in Data/*.txt .

Источник

for цикл в Bash

Циклы — одна из фундаментальных концепций языков программирования. Циклы удобны, когда вы хотите запускать серию команд снова и снова, пока не будет достигнуто определенное условие.

В языках сценариев, таких как Bash, циклы полезны для автоматизации повторяющихся задач. В Bash доступны три основные конструкции цикла: for , while и until циклы.

В этом руководстве мы рассмотрим основы циклов for в Bash. Мы также покажем вам, как использовать операторы break и continue чтобы изменить ход цикла.

Стандартный for цикл в Bash

Цикл for выполняет итерацию по списку элементов и выполняет заданный набор команд.

Цикл for Bash имеет следующую форму:

for item in [LIST] do [COMMANDS] done 

Список может быть серией строк, разделенных пробелами, диапазоном чисел, выводом команды, массивом и т. Д.

Оберните струны

В приведенном ниже примере цикл будет перебирать каждый элемент в списке строк, и переменный element будет установлен на текущий элемент:

for element in Hydrogen Helium Lithium Beryllium do echo "Element: $element" done 

Цикл выдаст следующий результат:

Element: Hydrogen Element: Helium Element: Lithium Element: Beryllium 

Цикл по диапазону чисел

Вы можете использовать выражение последовательности, чтобы указать диапазон чисел или символов, задав начальную и конечную точки диапазона. Выражение последовательности принимает следующую форму:

Вот пример цикла, который перебирает все числа от 0 до 3:

for i in 0..3> do echo "Number: $i" done 
Number: 0 Number: 1 Number: 2 Number: 3 

Начиная с Bash 4, также можно указывать приращение при использовании диапазонов. Выражение принимает следующий вид:

Вот пример, показывающий, как увеличить на 5:

for i in 0..20..5> do echo "Number: $i" done 
Number: 0 Number: 5 Number: 10 Number: 15 Number: 20 

Перебирать элементы массива

Вы также можете использовать цикл for для перебора массива элементов.

В приведенном ниже примере мы определяем массив с именем BOOKS и перебираем каждый элемент массива.

BOOKS=('In Search of Lost Time' 'Don Quixote' 'Ulysses' 'The Great Gatsby') for book in "$BOOKS[@]>"; do echo "Book: $book" done 
Book: In Search of Lost Time Book: Don Quixote Book: Ulysses Book: The Great Gatsby 

Цикл for в Bash в стиле C

Синтаксис цикла for стиле C имеет следующий вид:

for ((INITIALIZATION; TEST; STEP)) do [COMMANDS] done 

Часть INITIALIZATION выполняется только один раз при запуске цикла. Затем оценивается TEST . Если это ложь, цикл прекращается. Если TEST истинен, команды внутри цикла for выполняются, а часть STEP обновляется.

В следующем примере кода цикл начинается с инициализации i = 0 и перед каждой итерацией проверяется, является ли i ≤ 10 . Если true, он печатает текущее значение i и [увеличивает переменную] i на 1 ( i++ ), в противном случае цикл завершается.

for ((i = 0 ; i = 1000 ; i++)); do echo "Counter: $i" done 

Цикл повторится 1001 раз и выдаст следующий результат:

Counter: 0 Counter: 1 Counter: 2 . Counter: 998 Counter: 999 Counter: 1000 

Операторы break и continue

Операторы break и continue могут использоваться для управления выполнением цикла for.

Оператор break

Оператор break завершает текущий цикл и передает управление программой оператору, следующему за завершенным оператором. Обычно он используется для завершения цикла при выполнении определенного условия.

В следующем примере мы используем оператор if для прекращения выполнения цикла, когда текущий повторяемый элемент становится равным «Lithium».

for element in Hydrogen Helium Lithium Beryllium; do if [[ "$element" == 'Lithium' ]]; then break fi echo "Element: $element" done echo 'All Done!' 
Element: Hydrogen Element: Helium All Done! 

Оператор continue

Оператор continue завершает текущую итерацию цикла и передает управление программой следующей итерации цикла.

В следующем примере мы перебираем диапазон чисел. Когда текущий повторяемый элемент равен ‘2’, оператор continue заставит выполнение вернуться к началу цикла и продолжить следующую итерацию:

for i in 1..5>; do if [[ "$i" == '2' ]]; then continue fi echo "Number: $i" done 
Number: 1 Number: 3 Number: 4 Number: 5 

Примеров циклов for в Bash

Переименование файлов с пробелами в имени файла

В следующем примере показано, как переименовать все файлы в текущем каталоге с пробелом в его именах, заменив пробел на подчеркивание:

for file in * *; do mv "$file" "$file// /_>" done 

Давайте разберем код построчно:

  • Первая строка создает цикл for и выполняет итерацию по списку всех файлов с пробелом в имени. Выражение * * создает список.
  • Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя пробел знаком подчеркивания ( _ ). Часть $ использует расширение параметра оболочки для замены шаблона в параметре строкой.
  • done указывает конец сегмента цикла.

Изменение расширения файла

В следующем примере показано, как использовать цикл for в Bash for переименования всех файлов, оканчивающихся на .jpeg, в текущем каталоге путем замены расширения файла с .jpeg на .jpg.

for file in *.jpeg; do mv -- "$file" "$file%.jpeg>.jpg" done 

Давайте проанализируем код построчно:

  • Первая строка создает цикл for и выполняет итерацию по списку всех файлов, заканчивающихся на ‘.jpeg’.
  • Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя «.jpeg» на «.jpg». $ чтобы удалить часть ‘.jpeg’ из имени файла, используя расширение параметра оболочки
  • done указывает конец сегмента цикла.

Выводы

Цикл for Bash используется для повторного выполнения заданного набора команд определенное количество раз.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Источник

For files in directory, only echo filename (no path)

The quotes are needed in case $filename contains e.g. spaces.

Sorry for commenting on this old answer, but basename won't work correctly for files with space. Example: pwd output: /test 1 , basename $(pwd) output: test . Tested on OS X and Ubuntu Server (14.04). Native bash solution, as @SiegeX recommended, is what worked for me.

@YoungFrog thanks for the input, but that was 9 months ago. Also it would be better to use the variable $PWD instead of running the command.

echo $(basename /foo/bar/stuff) 

Why do you use echo ? basename already prints the results. echo may even mangle the result if you don't quote the subshell. Example: echo $(basename path/with\ \ spaces) incorrectly prints with spaces (only one space).

Another approach is to use ls when reading the file list within a directory so as to give you what you want, i.e. "just the file name/s". As opposed to reading the full file path and then extracting the "file name" component in the body of the for loop.

Example below that follows your original:

for filename in $(ls /home/user/) do echo $filename done; 

If you are running the script in the same directory as the files, then it simply becomes:

for filename in $(ls) do echo $filename done; 

ls includes any dotfiles where * expansion usually does not. Also for f in $(. ) . fails if any filename contains whitespace unless you set IFS, may fail if any filename contains a glob char unless you set -f/-o noglob, and depending on system or shell echo may fail if any filename is hyphen+letter or contains backslash. OTOH just ls -1 /path/to/dir all by itself reliably prints each filename on a line, modulo the dotfiles difference.

You can either use what SiegeX said above or if you aren't interested in learning/using parameter expansion, you can use:

for filename in $(ls /home/user/); do echo $filename done; 

Источник

Читайте также:  Kali linux температура процессора
Оцените статью
Adblock
detector