цикл оболочки соответствует регулярному выражению в текущей строке - PullRequest
0 голосов
/ 26 января 2012

Я пытаюсь создать скрипт для исправления CSV-файла следующим образом:

field_one,field_two,field_three
,field_two,field_three

Поэтому мне нужно проверить внутри цикла, если в текущей строке отсутствует field_one, и заменить его на sed с помощьюновое значение для field_one (перезаписать строку, пропущенную field_one).

Для этого у меня есть цикл, но мне нужна помощь с определением, отсутствует ли строка в первом поле или нет.Я, вероятно, должен использовать grep?но как использовать его в цикле и получить ответ?

while read -r line; do  
    # this is pseudocode:
    # if $line matches regex then
         #  sed 's/,/newfieldone/'
         #  overwrite the corrected line in the file
    # end if
done < my_file

Заранее большое спасибо за вашу помощь !!!!

Ответы [ 11 ]

3 голосов
/ 26 января 2012

Внутри вашего цикла вы можете запустить следующую команду sed:

sed 's/^\s*,/newfieldone,/'
2 голосов
/ 26 января 2012

Просто, черт возьми, вот решение в awk:

awk '{FS=","} {if ($1 == "") print "field_one" $0;else print $0} ' < /tmp/test.txt
2 голосов
/ 26 января 2012

Чтобы увидеть, начинается ли строка с , и, следовательно, отсутствует поле 1, вы можете использовать if [[ "$line" =~ ^, ]].

Например:

while read -r line; do  
  if [[ "$line" =~ ^, ]]
  then
    echo "newfieldone$line"
  else
    echo "$line"
  fi
done < my_file
1 голос
/ 27 января 2012

.,,и другой awk однострочный:

awk '$1==""{$1="field_one"}1' FS=',' OFS=',' file
1 голос
/ 26 января 2012

Это довольно короткий 1-вкладыш с awk

awk '{$1="field_one"}1' FS=',' OFS=',' file.csv
1 голос
/ 26 января 2012

Простое решение bash с использованием case statemetn:

while read -r line; do  
  case "$line" in
    ,*) printf "%s%s\n" newfieldone "$line" ;;
    *)  printf "%s\n" "$line" ;;
  esac
done < my_file

case использует сопоставление "глобус", а не регулярные выражения, поэтому ,* соответствует строке, начинающейся с запятой.

1 голос
/ 26 января 2012

с помощью sed попробуйте что-нибудь подобное:

sed -i 's|\(^,.*\)|new_field_one\1|g' <your file>
1 голос
/ 26 января 2012

Это может работать для вас:

a=Field_one,Field_two,Field_three
sed '/^,/c\'$a'' file
field_one,field_two,field_three
Field_one,Field_two,Field_three

Или, если просто вставить field_one:

a=Field_one
sed '/^,/s/^/'$a'/' file
field_one,field_two,field_three
Field_one,field_two,field_three
1 голос
/ 26 января 2012
$ sed -e "/^,/s/^,\([^,]*\),\([^,]\)/new_field_one,\1,\2/" < my_file

Редактировать: Возможно, это слишком сложно. Возьмите один из хороших ответов:)

1 голос
/ 26 января 2012
sed -i 's/^,/fieldone,/' YOURFILE

Заменит каждую строку, начинающуюся , на fieldone, (на месте, поэтому исходный файл будет перезаписан, если вам нужна резервная копия, попробуйте -i.backup).

Если вам нужно динамическое значение fieldone, это зависит от того, насколько динамичным оно будет :-), например ::

MYDYNAMICFIELDONE="DYNAF1"
sed -i "s/^,/${MYDYNAMICFIELDONE},/" YOURFILE

Или с вашей while петлей:

while read -r line; do  
    MYDYNAMICFIELDONE="SET IT"
    sed -i "s/^,/${MYDYNAMICFIELDONE},/"
done < my_file > tmpfile
mv tmpfile my_file

Или с awk:

awk '{
       /^,/ { 
               DYNAF1="SET IT HERE"
               print gensub("^,",DYNAF1 ",","g",$0)
            }
      } INPUT > OUTPUT
...