Объединение всех строк в одну строку с разделителем столбцов в unix

Вот мое решение на Python.

with open('/path/to/file', 'r') as f:
    for line in f:
        x=line.split(',')
        y=x[4].split('|')
        print(','.join(x[:4]) + ',' + str(min(y, key=lambda z: abs(float(z)-float(x[5])))))

Если у вас есть что-то вроде Pyed Piper, также известного как pyp, вы можете запустить его прямо из командной строки терминала:https://code.google.com/archive/p/pyp/

0
19.06.2020, 12:42
7 ответов
a=`awk -F ":" '{print $1}'  filename | perl -pne "s/\n/ /g"`
b=`awk -F ":" '{print $2}'  filename | perl -pne "s/\n/ /g"`
awk -v a="$a" -v b="$b" '{print a":"b;exit}'

выход

ABC  DEFG  MJk  : 123  4587  36

питон

#!/usr/bin/python
k=open('o.txt','r')
a=[]
b=[]
for i in k:
    u=i.split(":")[0]
    a.append(u)
    z=i.split(":")[1]
    b.append(z.strip())
print " ".join(a) +": "+ " ".join(b)

~

0
18.03.2021, 23:26

Казалось бы, нужно буферизовать весь контент. Вы можете попробовать следующее:

awk '{FNR==1{first=$1; second=$3} FNR>1{first=first " " $1; second=second " " $3} END{printf("%s : %s\n", first, second)}'

Это позволит аккумулировать содержимое всех «элементов первого столбца» всех строк в переменной first, а содержимое «элементов второго столбца» (фактически третьего,потому что :будет формировать собственный столбец с точки зрения awk)в переменной second. В конце он выводит накопленные таким образом буферы с символом-разделителем :.

Если начальные/конечные пробелы не являются проблемой, вы можете сократить код до

awk '{first=first " " $1; second=second " " $3} END{printf("%s : %s\n", first, second)}'
0
18.03.2021, 23:26

Это можно сделать по-разному, но я оставлю свой ответ в качестве примера без использования awk.

Предположим, что ваши данные находятся в файле data.dat, тогда решение:

echo "$(cut -d ':' -f 1 data.dat | tr '\n' ' ' | xargs) : $(cut -d ':' -f 2 data.dat | tr '\n' ' ' | xargs)"

Я получил следующий результат:

ABC DEFG MJk : 123 4587 36

Давайте перейдем к объяснению:

  • cut -d ':' -f 1 data.dat
    • cut— команда для получения части строки (, см.man cut)
    • -d ':'сообщает, что мы используем двоеточие в качестве разделителя
    • -f 1указывает извлечь только первый столбец (все, что осталось от двоеточия в вашем случае)
    • data.dat— это просто имя файла при сохранении ваших исходных данных
  • tr '\n' ' 'переводит новые строки изменений(\n)в пробелы, соединяющие выходные строки в одну строку
  • xargsздесь как уловка -без каких-либо аргументов эта команда перепечатывает каждое слово, обрезая лишние пробелы

Это почти то же самое со второй частью, за исключением того, что -f 2используется для извлечения строки слева от двоеточия.

Мы используем команду echoдля вывода результатов($(...)расширяет команду и помещает вывод команды в скобки в результате )двух анализов файла и соединяет их двоеточием между двумя проходами.

0
18.03.2021, 23:26
$ awk -F: '{a=a $1; b=b $2} END{print a FS b}' file
ABC DEFG MJk : 123 4587 36

В последнее время мы видим много сообщений, в которых люди используют tr '\n' ' 'или что-то подобное для преобразования новой строки во что-то другое. За исключением редких ситуаций, не делайте этого, так как он преобразует текстовый файл POSIX (, который могут читать все инструменты обработки текста POSIX ), во что-то другое, где YMMV. Текстовые строки POSIX заканчиваются на \n, а текстовый файл POSIX состоит из текстовых строк POSIX.Если вы используете trили что-то еще, чтобы удалить все символы новой строки, то то, что любой последующий инструмент обработки текста POSIX (awk, sed и т. д. и т. д. )может сделать с этим в качестве ввода, является неопределенным поведением.

Вот пример другого поведения, которого вы, возможно, не ожидаете, но которое на самом деле определено POSIX. Допустим, мы хотим преобразовать эту многострочную строку -в одну строку, разделенную пробелом -:

.
$ printf 'foo\nbar\n' | wc -l
       2

с помощью trудалить все \nс:

$ printf 'foo\nbar\n' | tr '\n' ' '
foo bar $
$ printf 'foo\nbar\n' | tr '\n' ' ' | wc -l
       0

по сравнению с лучшим способом сделать то же самое, который выводит текстовый файл POSIX и, таким образом, дает более интуитивно понятный результат при передаче вwc:

$ printf 'foo\nbar\n' | paste -sd ' ' -
foo bar
$ printf 'foo\nbar\n' | paste -sd ' ' - | wc -l
       1
4
18.03.2021, 23:26

Я бы предпочел сохранить каждый столбец в массиве, а затем распечатать их в нужном формате

awk -F" : " '{a[NR]=$1;b[NR]=$2} END{ for(i=1;i<=NR;i++) printf "%s ",a[i]; printf ": "; for(i=1;i<=NR;i++) printf "%s ",b[i];}' file
  • -F" : "разделяет столбцы на основе разделителя " : "
  • {a[NR]=$1;b[NR]=$2}создает два массива: индексы =NR(количество строк )и значения = значение столбца в этой строке
  • printfпечатает в нужном порядке(printfне печатаетnewline)
0
18.03.2021, 23:26

cut иpaste<()):

paste -s -d ' ' <(cut -d : -f 1 file) <(cut -d : -f 2 file) | paste -s -d :

Прочитать файл дважды, cutв соответствующие поля. pasteпоследовательно (дважды, сначала через пробел, затем через двоеточие ). paste -sзаменит <newline>каждой строки, кроме последней, на разделитель. Если пробелы уже есть во входном файле, измените первый разделитель pasteна пустую строку -d ''.

0
18.03.2021, 23:26

Это можно сделать с помощью редактора sed, добавив следующую строку в пространство шаблонов и перетасовав поля вокруг центрального двоеточия. Команда test повторяется до тех пор, пока не будет выбрана следующая строка.

sed -Ee '
  :a;$!N;s/(.*):(.*)\n(.*):(.*)/\1\3:\2\4/;ta
' file

Версия awk говорит сама за себя.

awk -F ':' -v ORS='' '
{ a[NR] = $1; b[NR] = $2 }
END {
  a[NR] = a[NR] FS
  for (i=1; i<=2*NR; i++)
     print i<=NR ? a[i] : b[i-NR]
  print RS
}
' file

Результат:

ABC DEFG MJK : 123 4587 36
2
18.03.2021, 23:26

Теги

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