New answers tagged

0

#! /usr/bin/perl use strict; use warnings; my %files=(); my @files=(); my $currentfile=''; my $maxcols=1; while(<>) { chomp; # a hash such as %files is inherently unordered, so store each # filename we process in @files, in the order that we see them. if ($currentfile ne $ARGV) { $currentfile = $ARGV ; push @files, $currentfile; }; ...


1

just a wild guess awk 'BEGINFILE { printf "%s",FILENAME} { printf ",%s",$0 ;} ENDFILE { printf "\n" ;}' file1.txt file2.txt file3.txt this will turn file to csv (but unquoted), file being converted to one line. replace ",%s" by "\t%s" to use tab.


0

First combine all the text files: cat Article1.txt Article2.txt Article3.txt > Result.txt Then convert the text file to CSV: (echo "Col1;Col2;Col3" ; cat Result.txt) | sed 's/;/<tab>/g' > file.csv


2

This shell script will get you the difference in seconds between the timestamps in column two of the first two rows: ( IFS=, read -r _ a _; IFS=, read -r _ b _; a=$(date --date $a +%s); b=$(date --date $b +%s); echo "$a - $b" | bc | tr -d - ) <filename It can be broken down like this, too, if you prefer: ( IFS=, read -r junk a junk # Get ...


0

This awk script will get you the difference in seconds between the timestamps in column two of the first two rows awk -F, '{ cmd = "date --date " $2 " +%s "; cmd | getline sec[NR] } NR>2 { exit } END { print (sec[2] > sec[1]) ? (sec[2] - sec[1]) : (sec[1] - sec[2]) }' <filename It can be broken down like this, too, if you prefer: awk -F, ' # ...


0

Here's how to get out the first two timestamps: head -2 mydata.csv | awk -F, '{print$2}' "Comparing" the times is a harder problem. If you just want to know which one is earlier, you can ask sort to check if they are in sorted order: if head -2 mydata.csv | awk -F, '{print$2}' | sort -c 2> /dev/null then echo "The first timestamp is earlier than ...


3

Let's decompose both commands num_rec=`cat test.csv |wc -l|tr -d " " | nawk '{printf("%0.6d\n", $1) }'` is a compounded command : A | B | C | D A: cat test.csv just cats the file test.csv (and is also a UUOC, "Useless Use Of Cat") B: wc -l will count the number of lines from its input (stdin), which is here test.csv's content. So it will count the ...


0

They're commands written by a novice who either hasn't learnt anything since the early 90s or is following a HOWTO from that era. Would be better written as: num_rec=$(wc -l <test.csv) num_rec=$(printf "%0.6d" $(( num_rec + 2 )) ) This uses command substitution to get the line count from test.cv using wc -l (by redirection, so that wc doesn't print ...


0

I'd pick up perl, because then you can split and join: #!/usr/bin/env perl use strict; use warnings; while ( <DATA> ) { chomp; my @fields = split /;/; s/\s+//g for @fields; print join ";", @fields, "\n"; } __DATA__ 03139; 5; IT1234978208; 20150930 ; CTZ 13/31.12.15; 03137; 6; IT1234978206; 20151015 ; CTZ 13/31.11.18; ...


6

It looks like you want to remove only those spaces that are before or after a semicolon. In that case: $ sed 's/[[:space:]]*;[[:space:]]*/;/g' text 03139;5;IT1234978208;20150930;CTZ 13/31.12.15; 03137;6;IT1234978206;20151015;CTZ 13/31.11.18; .... .... 03134;8;IT1234974406;20151212;CTZ 13/37.13.17; How it works: The sed substitution command typically ...


2

There may be a more shell-centric solution (awk?) but I usually turn to perl when the problem gets this complex. Here's a perl script that reads all of csv2 into memory, collecting the lines as keys into a hash whose values are the corresponding titles. It then loops through csv1, pulls out the title, then for each title from csv2, counts the number of ...


1

I would get all the titles from your first file with something like interesting_titles=$(cat $input |cut -d, -f2) then use that to grep your second file for those titles grep -F "$interesting_titles" $csv2 Anything returned by grep would be a match. You can shorten this to a one-liner with grep -F "$(cat $input |cut -d, -f2)" $csv2 If you want the ...


0

The easiest thing to do if you control the input format you expect is to read the entire file into python, extract with a regular expression the table of interest, then pass this to csv: import csv, re data = open("foo.org").read() mo = re.search("TBLNAME: table1\n.*?\n(\n|$)", data, re.S) mytable = mo.group(0) d = csv.DictReader(mytable.splitlines(), ...


0

You could write a Python function that reads and adds the lines whose first and last character is a '|' to a table (which could be a list object where each item is one line of the table). If you have several tables, a line not beginning with '|' is the hint for 'end-of-table'.


0

OK, so the best solution for me (but I guess it's a matter of taste), was using PHP's fgetcsv, since I already have PHP on that server. It's a pity the bash read command doesn't handle the newlines as well as the PHP function. It automatically recognises additional delimiters (like "'s). Sample: <?php $row = 1; if (($handle = fopen("test.csv", "r")) !== ...


1

#!/usr/bin/awk -f { w[FNR][FILENAME] = $0 } END { for (x in w) print w[x][ARGV[1]] ";" w[x][ARGV[2]] } I also came up with this, but it fails because of the way Awk iterates arrays: #!/usr/bin/awk -f { w[FNR][FILENAME] = $0 } END { for (x in w) { y = 0 for (z in w[x]) { printf w[x][z] printf y ? "\n" : ";" y = 1 } ...


1

You should really be using a proper CSV parser. For example, using the one that ships with ruby: ruby -rcsv -e 'CSV.foreach("file", :col_sep => "|") {|row| p row; puts row[1]}' we get ["aaa", "111", "!!!", ""] 111 ["bbb", "222", "@@\n@", ""] 222 ["ccc", "333", "###", ""] 333 You can see for the 2nd row, there is the embedded newline. Remove p row to ...


3

For a shell with a read builtin that can handle CSV, you can use ksh93 instead of bash: $ while IFS='|' read -rS a b c; do printf '%s\n' "$b"; done < file 111 222 333 To convert that format to something that bash's read can handle, you could do: < file ksh93 -c 'while IFS="|" read -rSA a; do printf "%s|" "${a[@]//[\|]/\\\0}" ...


2

sed -r ':;s/(\|.*)\|(.*\|.*\|)/\1\2/;t' Deletes every pipe that is preceeded by one and followed by two pipes. If you want to edit the file in place use -i option.


1

Following terdon's advice, im adding an alternative approach using sed, i mainly include it for completeness, however unlike the awk '{printf "%s,", $1}' which aggregates whilst ommitting the newline, with sedwe are actively replacing the newlines, thus it would also fit in when we wanted to replace a different character. It is inefficient though. The ...


2

All you need to do is parse the command's output and replace the first newline (\n) with a comma. This should work: ssh test01 "hostname && cat /etc/sysconfig/rhn/rhnsd " | perl -00pe 's/\n/,/' Here we're using perl to slurp the entire file into memory (-0) and replace the first \n with a comma. The -p tells perl to print each input "line" ...


0

For your command this would produce the expected output : counter=0 ssh test01 "hostname && cat /etc/sysconfig/rhn/rhnsd " \ | while read line ; do ((counter++)) if [[ counter -eq 1 ]]; then echo -ne "${line}," else echo "$line" fi done



Top 50 recent answers are included