#shell #unix #sed #cut
#оболочка #unix #sed #вырезать
Вопрос:
У меня есть случай, когда я должен заменить число 1 на число 3 в 10-м расположении различных строк в сохраненном текстовом файле. Я не могу найти способ сделать это. Ниже приведен пример файла и кода.
Пример файла:
$ cat testdata.txt
1 43515 8 1 victor Samuel 20190112
3215736 4 6 Michael pristine 20180923
1 56261 1 1 John Carter 19880712
#!/bin/sh
filename=testdata.txt
echo "reading number of line"
nol=$(cat $filename | wc -l)
flag[$nol]=''
echo "reading content of file"
for i in (1..$nol)
do
flag=($cut -c10-11 $filename)
if($flag==1)
sed 's/1/3/2'
fi
done
Но это не работает.
Пожалуйста, помогите решить эту проблему.
Обновлено:
Пример вывода:
1 43515 8 1 victor Samuel 20190112
3215736 4 6 Michael pristine 20180923
1 56261 3 1 John Carter 19880712
Комментарии:
1. Пожалуйста, взгляните: shellcheck.net
2. Вам также необходимо предоставить пример вывода. Ваше описание проблемы довольно краткое и немного неясное
3. Это не похоже на подходящие инструменты для работы. Как насчет использования языка программирования, более ориентированного на обработку строк, такого как awk, perl или python? Было бы довольно просто сделать это с помощью одного из них, и в большинстве систем Linux все они предустановлены.
4. Причина использования сценария оболочки заключается в том, что я использую pig для хранения сложных данных во внешней таблице hive, а затем генерирую файлы оболочкой после некоторых манипуляций.
Ответ №1:
попробуйте это
sed "s/^(.{8}) 1 (.*)$/1 3 2/g" testdata.txt > new_testdata.txt
Если sed поддерживает опцию -i, вы также можете редактировать на месте.
sed -i "s/^(.{8}) 1 (.*)$/1 3 2/g" testdata.txt
вывод
1 43515 8 1 victor Samuel 20190112
3215736 4 6 Michael pristine 20180923
1 56261 3 1 John Carter 19880712
объяснение
s # substitute
/^( # from start of line, save into arg1
.{8} # the first 8 characters
) 1 ( # search pattern ' 1 '
.* # save the rest into arg2
)$/ # to the end of the line
1 3 2 # output: arg1 3 arg2
/g # global on whole line
Комментарии:
1. Некоторые небольшие улучшения: Вам не нужен глобальный флаг. Сопоставление подстроки после `1` устарело. Когда
sed
поддерживает это. флаг-r
помогает избежать обратной косой черты:sed -ri 's/^(.{8}) 1 /1 3 /' testdata.txt
2. Спасибо @UtLax, это очень помогло. Объяснение, данное вами, очень помогло понять выражение.