Linux column to string

Convert specified column in a multi-line string into single comma-separated line

I like solutions like this too but is the -e arg necessary here since there’s only the first command being used for sed? I believe cat data.txt | xargs | sed ‘s/ /, /g’ would work all the same. For example, echo -e «foo\nbar\nbazz» | xargs | sed ‘s/ /, /g’ outputs foo, bar, bazz.

cut -d' ' -f5 file | paste -d',' -s +12.0,+15.5,+9.0,+13.5 

For each line in the file; chop off the first field and spaces following, chop off the remainder of the line following the second field and append to the hold space. Delete all lines except the last where we swap to the hold space and after deleting the introduced newline at the start, convert all newlines to , ‘s.

$ awk -v ORS=, '' data.txt | sed 's/,$//' +12.0,+15.5,+9.0,+13.5 
$ cat data.txt | tr -s ' ' | cut -d ' ' -f 2 | tr '\n' ',' | sed 's/,$//' +12.0,+15.5,+9.0,+13.5 

cheers, what about if the input to awk was through standard input (just put function | awk. in your example?

awk one liner

Format specifier «%s», should be added after printf to make it more robust i.e. to make it work with all kind of rows such as «foo %s».

which finds the string starting with + , followed by any string \S\+ , then convert new line characters into commas. This should be pretty quick for large files.

sedSelectNumbers='s".* \(+8*[.]3*\) .*"\1,"' sedClearLastComma='s"\(.*\),$"\1"' cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma" 

the good thing is the easy part of deleting newline «\n» characters!

EDIT: another great way to join lines into a single line with sed is this: |sed ‘:a;N;$!ba;s/\n/ /g’ got from here.

A solution written in pure Bash:

#!/bin/bash sometext="something1: +12.0 (some unnecessary trailing data (this must go)) something2: +15.5 (some more unnecessary trailing data) something4: +9.0 (some other unnecessary data) something1: +13.5 (blah blah blah)" a=() while read -r a1 a2 a3; do # we can add some code here to check valid values or modify them a+=("$") done " # between parenthesis to modify IFS for the current statement only (IFS=',' ; printf '%s: %s\n' "Result" "$") 

Don’t seen this simple solution with awk

fg@erwin ~ $ perl -ne 'push @l, (split(/\s+/))[1]; END < print join(",", @l) . "\n" >'  

You can also do it with two sed calls:

$ cat file.txt something1: +12.0 (some unnecessary trailing data (this must go)) something2: +15.5 (some more unnecessary trailing data) something4: +9.0 (some other unnecessary data) something1: +13.5 (blah blah blah) $ sed 's/^[^:]*: *\([+0-9.]\+\) .*/\1/' file.txt | sed -e :a -e '$!N; s/\n/,/; ta' +12.0,+15.5,+9.0,+13.5 

First sed call removes uninteresting data, and the second join all lines.

You can also print like this:

Just awk: using printf

bash-3.2$ cat sample.log something1: +12.0 (some unnecessary trailing data (this must go)) something2: +15.5 (some more unnecessary trailing data) something4: +9.0 (some other unnecessary data) something1: +13.5 (blah blah blah) bash-3.2$ awk ' < if($2 != "") < if(NR==1) < printf $2 >else < printf "," $2 >> >' sample.log +12.0,+15.5,+9.0,+13.5 

Another Perl solution, similar to Dan Fego's awk:

perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/' 

-a tells perl to split the input line into the @F array, which is indexed starting at 0.

Well the hardest part probably is selecting the second "column" since I wouldn't know of an easy way to treat multiple spaces as one. For the rest it's easy. Use bash substitutions.

# cat bla.txt something1: +12.0 (some unnecessary trailing data (this must go)) something2: +15.5 (some more unnecessary trailing data) something4: +9.0 (some other unnecessary data) something1: +13.5 (blah blah blah) # cat bla.sh OLDIFS=$IFS IFS=$'\n' for i in $(cat bla.txt); do i=$(echo "$i" | awk '') u="$$i" done IFS=$OLDIFS echo "$u" # bash ./bla.sh +12.0, +15.5, +9.0, +13.5 

Источник

Convert array type variable to string type with space delimiter

If the first character of IFS variable is a space (which it is by default), you can use the star index in double quotes.

#! /bin/bash arr[0]=2019-06-26 arr[1]=15:21:54 string="$" printf "'%s'" "$string" 

Documented under Special Parameters:

When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable.

For completeness, while the "$" Korn syntax (extended from the Bourne "$*" special parameter) would also work in zsh, in zsh, you may want to use the j (for join) parameter expansion flag instead which allows you to use any arbitrary joining string and doesn't need to rely on a global parameter like $IFS :

Note that for "$" , ksh (both ksh93 and mksh) join on the first byte of $IFS instead of first character. That matters for multi-byte characters like:

$ ksh -c 'a=(foo bar); IFS="⇅"; echo "$"' foo�bar $ mksh -c 'a=(foo bar); IFS="⇅"; echo "$"' foo�bar $ mksh -o utf8-mode -c 'a=(foo bar); IFS="⇅"; echo "$"' foo�bar 

(where that � is how my terminal emulator rendered the first byte (0xe2) of that ⇅ character which by itself doesn't form a valid character).

Other Korn-like shells with array support are OK:

$ bash -c 'a=(foo bar); IFS="⇅"; echo "$"' foo⇅bar $ zsh -c 'a=(foo bar); IFS="⇅"; echo "$"' foo⇅bar $ yash -c 'a=(foo bar); IFS="⇅"; echo "$"' foo⇅bar 

Источник

column to row using "," as delimter

I have a list of objects in column (file_column.txt) and I want to transpose this objects in row using "," as delimiter in a new file (file_row.txt). Es.

file_column.txt: Art 14f adr a24 file_row.txt: Art,14f,adr,a24 

2 Answers 2

You have to use the right delimiter (comma) with the -d parameter:

paste -sd, file Art,14f,adr,a24 

You have carriage returns in the files. Run dos2unix on any input file. What you described is possibly the result of having ^M or \r , Windows line endings, at the end of your file lines.

#! /bin/bash while read line do string="$,$" done < file_column.txt echo $> file_row.txt 

The while read construction is more portable as it uses only Bash syntax and the builtin read .

Paste is a POSIX tool, Bash is not, so the portability claim is not true (although that script does not contain any bashism). Also see Why is using a shell loop to process text considered bad practice?.

Hey, no intention to destroy, only to constructively criticize 😉 And I guess we have all been there as well!

You must log in to answer this question.

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.12.43529

Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of The Open Group.
This site is not affiliated with Linus Torvalds or The Open Group in any way.

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Bash: преобразование столбца текста в строку

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

Archlinux
Debian
Ubuntu
Kaos
мягкая фетровая шляпа
Slackware
папуасских

И мы хотим превратить это в:

Archlinux, Debian, Ubuntu, Каос, Fedora, Slackware, Gentoo

Для этого мы будем использовать для цикла y un эхо -n :

Это покажет нам желаемый результат в терминале, если, с другой стороны, мы хотим, чтобы он был сохранен в другом файле .txt, мы перенаправляем вывод:

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

Содержание статьи соответствует нашим принципам редакционная этика. Чтобы сообщить об ошибке, нажмите здесь.

Полный путь к статье: Из Linux » Учебники / Руководства / Советы » Bash: преобразование столбца текста в строку

15 комментариев, оставьте свой

Оставьте свой комментарий Отменить ответ

Если в .odt у меня есть 2 столбца на каждой странице, они читаются так: стр.1
столбец 1 столбец 2
стр.2
столбец 3 столбец 4
и так далее Как мне расположить каждый столбец ниже другого?
столбец 1
столбец 2
столбец 3
столбец 4
и так далее

Намного легче: Если вы хотите разделить табуляцией:
Вы пишете: paste -s distros.txt
Вы получаете: archlinux debian ubuntu kaos fedora slackware gentoo Если вы хотите, чтобы он был разделен пробелами:
Вы пишете: paste -s -d »» distros.txt
Вы получаете: archlinux debian ubuntu kaos fedora slackware gentoo Если вы хотите разделить его запятыми:
Вы пишете: paste -s -d, distros.txt
Вы получаете: archlinux, debian, ubuntu, kaos, fedora, slackware, gentoo С paste, cat, awk и другими друзьями, проявив немного изобретательности, вы можете составить множество полезных комбинаций, не усложняя себе жизнь. Пусть все будет отлично, поздравляем с наградой в Portalprogramas!

Я использовал sed, awk, cut, sort, uniq, короче крем, но никогда не обращал внимания на paste, спасибо за то, что показал, на что он способен. Slds.

Источник

Parse all column elements from a linux bash command output

OR to make it print multiple columns using a colon delimited list:

awk -v col='2:7' ' BEGIN n < for (i=1; i in arr; ++i) printf "%s%s", $arr[i], (i < n ? OFS : ORS) >' file 

With bash you can use 'read -a', this reads a line from standard input, splits using IFS field separator which has space by default and populates array variable which can be referenced as $ (zero based).

while read -a arr; do echo "$" echo "$" done 

Unfortunately lsscsi does not provide consistent parseable output nor the chance to change the field separator as far as I see. With two different harddisks on the same system the column for the device is differing by one! The following code sniplet should give you an idea about what I mean and how I worked around it. at least to get the device which is at the end of the line. To get the product name and the product revision correctly, it could also be an idea to call each device with lssci -c a:b:c:d and then parse this output.

lsscsi > /tmp/tmp$$.out while read line do echo $line echo 012345678901234567890123456789012345678901234567890123456789 echo 0. 1. 2. 3. 4. 5. $line | cut -c2) TYPE=$(echo $line | cut -c16-18) PRODUCT=$(echo $line | sed -n 's/.\\(.*\) *\/dev\/.*/\1/p') DEVICE=$(echo $line | sed -n 's/.\.*\/dev\/\(.*\)/\1/p') echo $ID-$TYPE-$DEVICE-$PRODUCT done 

Another easy way to do it without awk :

lsscsi | tr -s ' ' | cut -d' ' -f7

The last flag specifies the column.

Tested it again on a Linux machine and it works fine. My lsscsi output only has four columns, and therefore I use -f4 for the final argument. All output is treated as text in the shell, and in this case, we force separation by single space.

Источник

Читайте также:  Ati mobility radeon hd 4570 linux
Оцените статью
Adblock
detector