Заменить позиции на другие позиции в файле

Утсав дал вам правильное решение. Проблема заключалась в том, что вы присваивали значение переменной с именем echo.

Тем не менее, я дам еще несколько советов по улучшению вашего скрипта.

В настоящее время вы не можете выбрать папку с именем 1. Кроме того, сценарий излишне интерактивен и вообще не взаимодействует с пользователем. Если бы пользователь, например, указал имя папки в командной строке при вызове сценария, вам вообще не пришлось бы запрашивать имя папки. Только когда пользователь не указал имя папки, вам нужно будет использовать текущий рабочий каталог:

#!/bin/sh

folder="$1"

if [ -z "$folder" ]; then
    printf 'No folder given, using "%s"\n' "$PWD" >&2
    folder="$PWD"
fi

Тогда зачем вообще заставлять пользователя вводить имя файла в этой папке? Вы можете попросить их выбрать файл из меню :

.
select file in "$folder"/*; do
    printf 'Making "%s" executable with "sudo chmod +x"\n' "$file"
    sudo chmod +x "$folder/$file"
    break
done

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

#!/bin/sh

folder="$1"

if [ -z "$folder" ]; then
    printf 'No folder given, using "%s"\n' "$PWD" >&2
    folder="$PWD"
elif [ -f "$folder" ]; then
    # $folder is actually a file, chmod it and we're done
    sudo chmod +x "$folder"
    exit
fi

if [ ! -d "$folder" ]; then
    printf 'No such folder: %s\n' "$folder" 2>&1
    exit 1
fi

select file in "$folder"/*; do
    printf 'Making "%s" executable with "sudo chmod +x"\n' "$file"
    sudo chmod +x "$folder/$file"
    break
done

Если этот скрипт называется script.sh, то его можно будет запустить следующими способами:

$./script.sh                  # asks for file in current folder
$./script.sh myfolder         # asks for file in "myfolder"
$./script.sh myfolder/myfile  # quietly chmods "myfolder/myfile"
1
27.08.2019, 16:59
3 ответа

Довольно короткий awkодин -вкладыш:

$ awk '/^D/ { nr = substr($0,2,7); $0 = sprintf("D%07dACCT_%-10d%s", nr, nr, substr($0,24)) } { print }' file
H20190105
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678

Код awkобнаружит строки, которые необходимо изменить, по наличию Dв первой позиции.

Новая строка состоит из sprintf()из нулевого -заполненного числа после D, строки ACCT_, за которой следует то же число снова (теперь не ноль -заполнено ), и, наконец, все, что было в и после позиции 24 в строке.

Печатаются все строки (, измененные, как описано выше, или не измененные вовсе ).

2
27.01.2020, 23:30
$ awk 'NF>1{$0=sprintf("%sACCT_%-11d%s", substr($0,1,8), substr($0,2,7), substr($0,24))} 1' file
H20190105
D0012345ACCT_12345      100001072010
D0008912ACCT_8912       450023082005
T0001245678
0
27.01.2020, 23:30
$ perl -pe 's/^(D)(.{7})(.{12})/sprintf("%s%s%s%-7s",$1,$2,"ACCT_",$2+0)/e' input.txt 
H20190105                         
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678                       

Здесь используется модификатор Perl eдля оператора s/LHS/RHS/, так что он выполняет RHS как код perl. $2+0неявно преобразует $2 из строки, дополненной нулями -, в число, которое автоматически удаляет все начальные нули. Формат sprintf()гарантирует, что длина поля выходной строки точно такая же, как и входная.


Или для ремонта awkодного -вкладыша:

$ awk '/^D/{$0=substr($0,1,8)"ACCT_"sprintf("%-7s",substr($0,2,7)+0)"  "substr($0,24,length($0))} 1' input.txt 
H20190105                         
D0012345ACCT_12345    100001072010
D0008912ACCT_8912     450023082005
T0001245678                       

awkтоже имеет sprintf. IMO, это сложнее читать и понимать, чем версию Perl. YMMV.

Другая awkверсия, похожая на версию perl:

$ awk '
   /^D/ {
     ac=sprintf("%-7s",substr($0,2,7)+0);
     $0=gensub("^(D)(.{7})(.{12})","\\1\\2ACCT_"ac,1)
   }
   1' input.txt 
H20190105                         
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678                       

Если вам не нужно удаление нуля -, это можно сделать с помощьюsed:

$ sed -E -e 's/^(D)(.{7})(.{12})/\1\2ACCT_\2/' input.txt 
H20190105                         
D0012345ACCT_0012345   100001072010
D0008912ACCT_0008912   450023082005
T0001245678                       
0
27.01.2020, 23:30

Теги

Похожие вопросы