Извлечение данных из текстового файла с использованием bash

Я ищу скрипт bash. В текстовом файле у меня есть такие данные:

+------+------
| Id   | User | 
+------+------+
| 8192 | root | 
| 8194 | root |
| 8202 | root |
| 8245 | root | 
| 8434 | root |  
| 8754 | root | 
| 8761 | root | 
| 8762 | root | 
| 8764 | root | 
| 8771 | root | 
+------+------+

Я хочу извлечь данные следующим образом:

8192,8194,8202,8245,8434,8754,8761, 8762,8764

Я имею в виду, мне нужно первое поле, содержащее числа, но не последнее. И все извлеченные числа должны быть разделены запятой (,).

Может ли кто-нибудь помочь мне получить это?

4
задан 24 February 2014 в 20:58

5 ответов

Вам не нужен сценарий для такой простой вещи. Можно использовать awk:

awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' file.txt | head -n -1 | awk '{print}' ORS=',' | sed 's/,$/\n/'

Некоторые объяснения:

  • awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' file.txt - печатают от file.txt только поля, которые являются числами.
  • head -n -1 - удаляют последнюю строку / последнее число.
  • awk '{print}' ORS=',' - связывают все строки в одной одной строке, каждое число, разделенное ,.
  • sed 's/,$/\n/' - заменяют в последний раз , символом новой строки.

Или, короче:

awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' ORS=',' file.txt | sed 's/,[0-9]*,$/\n/'
0
ответ дан 24 February 2014 в 20:58

Самым самым коротким путем я могу найти:

echo `sed 's/[^0-9]//g' your_file` | sed 's/ /,/g'

Результат:

8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

[^0-9] - означает, что все кроме numericals

s/[^0-9]//g - удаляет все кроме Замены numericals

your_file с путем к Вашему файлу

<час>

Для Вас наконец задача, с kill команда. Быть тщательно при использовании этой строки, это уничтожит каждый PID в списке :

for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ 

Перед выполненной предыдущей строкой, можно хотеть выполнить эту строку:

for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ 

Это покажет что-то вроде этого:

kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час>

Удачи!

`; do echo "kill -9 $pid";done

Это покажет что-то вроде этого:

kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час>

Удачи!

`; do kill -9 $pid;done

Перед выполненной предыдущей строкой, можно хотеть выполнить эту строку:

for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ 

Это покажет что-то вроде этого:

kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час>

Удачи!

`; do echo "kill -9 $pid";done

Это покажет что-то вроде этого:

kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час>

Удачи!

0
ответ дан 24 February 2014 в 20:58

Вот один лайнер для Вашей цели,

sed 's/[^0-9]//g' file.txt| xargs | sed 's/ /,/g'

или

sed 's/[+|IdUserroot\-]*//g' file.txt | xargs | sed 's/ /,/g'

Вывод:

8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

Объяснение

man sed

s/regexp/replacement/
          Attempt  to  match  regexp  against the pattern space.  If successful, replace that
          portion matched with replacement.  The replacement may contain the special  charac‐
          ter  & to refer to that portion of the pattern space which matched, and the special
          escapes \1 through \9 to refer to the corresponding matching sub-expressions in the
          regexp.

g     Copy/append hold space to pattern space.

Регулярное выражение <глоток> [Википедия]

[^ ]    Matches a single character that is not contained within the brackets.
For example, [^abc] matches any character other than "a", "b", or "c". [^0-9]
matches any single character that is not a number from "0" to "9".

Следовательно использование sed я заменил все пространством. Затем xargs помещает их в строку, разделенную пространством,

$ sed 's/[^0-9]//g' file.txt| xargs
8192 8194 8202 8245 8434 8754 8761 8762 8764 8771

Наконец шаг, я заменил все пробелы , использование sed

0
ответ дан 24 February 2014 в 20:58

где текст находится в input файл в том же каталоге, и результат дан в output файл.

cat ./input | sed -e 's/+------+------+//g' | sed -e 's/| Id   | User |//g' | sed -e 's/ | root |//g' | tr -d "\n" | sed -e 's/| /,/g' | sed -e 's/ ,/,/g' | sed -e 's/ ,/,/g' > output

, Когда я сделал это Ваш пример, я добрался:

+------+------,8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

, Который может, потому что верхняя строка Вашего примера отсутствовала + - может быть несколько других ошибок...

Тогда я думаю, что просто необходимо добавить sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill вначале

<час>

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

cat ./input | sed 's/[+-]*//g' | sed 's/ | root |//g' | tr -d "\n" | sed 's/| /,/g' | sed 's/ ,/,/g' | sed 's/ ,/,/g' | sed 's/^,//' | sed 's/,[0-9]* $/\n/' | sed 's/Id//g' | sed 's/,User,,//g' | sed 's/ //g' > output

Затем на основе Вас Q& здесь , необходимо быть в состоянии работать:

sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)

, хотя можно хотеть проверить, является ли это правильной командой с этим сначала:

echo "sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)"
0
ответ дан 24 February 2014 в 20:58

Я думаю, что это - то, в чем Вы нуждались. Некоторым другим ответам не удалось удалить последнюю часть.

sed -n 's/.*\([0-9]\{4\}\).*/\1/p' file | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$/\1/g'

А небольшой пример,

$ (echo '| Id   | User |'; echo '| 8192 | root |'; echo '| 8194 | root |'; echo '| 8771 | root |') | sed -n 's+.*\([0-9]\{4\}\).*+\1+p' | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$/\1/g'
8192,8194
0
ответ дан 24 February 2014 в 20:58

Другие вопросы по тегам:

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