Как увеличить и уменьшить значения в CSV из оболочки - PullRequest
0 голосов
/ 04 декабря 2011

У меня есть CSV-файл, как, скажем, table.csv

foo;3
bar;1

и скрипт

#!/bin/bash
[..]
# increment ${searchterm} by one
eval [..]
# decrement ${searchterm} by one

, и моя проблема состоит в том, чтобы заменить правую строку и значение увеличенным целым числом.Кроме того: если searchterm отсутствует в файле, его следует принять равным 0.

Цель состоит в том, чтобы получить машиночитаемый обзор числа процессов в различных операторах eval.

awk или sed могут быть решениями, но я не нашел подсказки.

Редактировать: Привет, поскольку ответ @ shellter уже решил мою проблему, я только пытаюсь получить более точную информацию для документации.С помощью ввода "foo" я хотел увеличить значение до

foo;4
bar;1

и после выполнения инструкции eval вернуться к исходным значениям.С помощью ввода "demo" я хочу получить вывод типа

foo;3
bar;1
demo;1

, а затем вернуться к

foo;3
bar;1
demo;0

afterwords.

Идея состоит в том, чтобы иметьвесь сценарий выполняется в нескольких экземплярах одновременно и может считывать количество экземпляров из таблицы .csv.

1 Ответ

0 голосов
/ 05 декабря 2011

с учетом ваших данных и вашего разреженного описания (это всегда хорошо, чтобы показать результат, который вам нужен / ожидаемый И и любые сообщения об ошибках, которые вы получаете), попробуйте это

cat myData
foo;3
bar;1

cat myFixer.sh
#!/bin/bash
awk '
  BEGIN {FS=";" ; OFS=";"}
  {
     if ($1 == target ) {
       $2 += incr
       targFound=1
     }
     print $0
  }
  END { 
    if (! ( targFound) ) {
      print target OFS "0"
    }
  }'  target="foo" incr=3 myData

 # output
 foo;6
 bar;1

 foo;3
 bar;1
 BAD;0

Я использую incr=3, чтобы показать, что это общее решение.Если вам нужно увеличение +1, просто измените аргумент на incr=1.

Некоторые awks хотят видеть переменные командной строки, установленные как -v target=foo -v incr=3.

Вы можете легко изменитьэтот bash-скрипт, принимающий аргументы для target и incr, входной файл в виде $ 1 $ 2 $ 3.

Прямо сейчас вывод просто появляется на вашем экране.Я бы порекомендовал перенаправить вывод в новый файл.

myFixer.sh > myData.New 

Обратите внимание, что FS - это специальная переменная awk, что означает FieldSeparator.OFS - это OutputFieldSeparator, поэтому в вашем случае можно легко преобразовать в истинный CSV, изменив OFS на OFS = ","

Awk анализирует каждую строку ввода в полях;вся строка называется $ 0, в то время как каждому элементу, разделенному с помощью FS (в вашем случае ';'), присваивается последовательный номер, перемещающийся слева направо, поэтому первое поле называется $ 1, второе - $ 2 и т. д.Awk имеет много других внутренних переменных, включая NF (Number_of_Fields), который устанавливается для каждой строки считываемых данных.Вы можете использовать NF отдельно для проверки правильности количества полей в строке (для одного примера) или вы можете «разыменовать» значение NF с помощью символа «$» и иметь доступ к последнему значению в каждой строке с помощью'$ NF.Для вашего примера, мы могли бы переписать $ 2 как $ NF.

Действие по умолчанию для awk, заданного кода в блоках {..}, состоит в том, чтобы прочитать каждую строку ввода и затем обработать ее в соответствии с логикой внутри блока.В вашем случае, мы смотрим на поле один, чтобы увидеть, является ли это целевой строкой, и если это так, мы увеличиваем значение там.

Для всех записей мы выводим полную строку, независимо от того, была ли онаувеличивается или нет.

Блок кода BEGIN выполняется перед чтением любых записей из входных файлов и является способом инициализации переменных (или в этом случае вы переопределяете значение по умолчанию FS).

Блок END выполняется после прочтения всех входных файлов.Поскольку вам нужно вывести foo; 0, если его там нет, мы сохраняем флаг, чтобы указать, была ли найдена ваша цель поиска или нет.Последнее, что мы делаем, это проверяем, была ли цель найдена, и если нет, выдают строку с 'target OFS 0' в качестве текста.

Надеюсь, это поможет.

PS

Добро пожаловать в StackOverflow, пожалуйста, позвольте мне напомнить вам о трех вещах, которые мы обычно делаем здесь: 1) Получая помощь, постарайтесь также помочь ей, отвечая на вопросы в вашей области знаний 2) Читайте часто задаваемые вопросы, http://tinyurl.com/2vycnvr, 3) Когда вы видите хорошие вопросы и ответы, оцените их, используя серые треугольники, http://i.imgur.com/kygEP.png, поскольку доверие к системе основано на репутации, которую пользователи получают, делясь своими знаниями.Также не забудьте принять ответ, который лучше решит вашу проблему, если таковой имеется, нажав на значок галочки, http://i.imgur.com/uqJeW.png

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