У меня чертовски сложно получить правильный синтаксис, используя sed
с переменными, содержащими путь к файлу, обратный вызов регулярного выражения и арифметическое выражение. Я не знаю, как правильно избегать вещей.
У меня есть путь к файлу в текстовом файле с номером рядом с ним. Я хочу найти эту строку и увеличить число.
FILE="/home/username/scripts/test.txt"
LINE="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
sed -i -e "s,'$LINE' \([0-9]*\),'$LINE' $((\1+1))," $FILE
Например ..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
должно стать ..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
Каков наилучший способ избежать "." в пути к файлу? Как правильно реализовать обратный вызов \1
и арифметическое выражение $((\1+1)
?
В настоящее время я получаю неверный токен \1+1
.
sed
и арифметика не смешивается. Правильный инструмент для заданий как это awk
.
Рассмотрите этот тестовый файл:
$ cat test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
/another/non/matching/line 5
Мы можем увеличить количество строки, с которой Вы хотите:
$ line="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
$ awk -v f="$line" '$0~f {$NF++} 1' test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
/another/non/matching/line 5
Как Вы видите, это увеличило число на строке, которая соответствовала $line
.
Одно ограничение - то, что этот код, как записано, не сохранит несколько пробелов на строках, для которых увеличено число. Если бы пробел важен, нам было бы нужно больше определения формата ввода.
-v f="$line"
Это присваивает значение переменной оболочки line
к awk переменной f
.
$0~f {$NF++}
Здесь, $0~f
условие. Это верно если входная строка, обозначенная $0
, соответствует regex f
как определено выше. Если это соответствует, то оператор $NF++
выполняется. Это увеличивает последнее поле на строке, которая, для Вашего входа, является числом.
1
Это - загадочное сокращение awk от печати строки.
awk
Если у Вас есть современный GNU awk, можно отредактировать файл на месте с:
gawk -i inplace -v f="$line" '$0~f {$NF++} 1' test.txt
С другим awks используйте:
awk -v f="$line" '$0~f {$NF++} 1' test.txt > tmp.txt && mv -f tmp.txt test.txt
text.txt
если это не существуетВ случае, что файл test.txt
не содержит соответствие строки $line
, эта версия будет такая строка с 1
как количество:
gawk -i inplace -v f="$line" '$0~f {n=1; $NF++} 1; END{if(!n) print f,1>>FILENAME}' test.txt
Этот код добавляет переменную n
. Если $line
находится в файле, n
установлен на 1
. Если это не, n
остается в значении по умолчанию 0
. В END
из входного файла, значения n
тестируется. Если n
все еще нуль, строка добавляется.