Hot answers tagged

143

Use cut with _ as the field delimiter and get desired fields: A="$(cut -d'_' -f2 <<<'one_two_three_four_five')" B="$(cut -d'_' -f4 <<<'one_two_three_four_five')" You can also use echo and pipe instead of Here string: A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)" B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)" Example: $ s=...


74

cut sounds like a suitable tool for this: bash-4.2$ s='id;some text here with possible ; inside' bash-4.2$ id="$( cut -d ';' -f 1 <<< "$s" )"; echo "$id" id bash-4.2$ string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string" some text here with possible ; inside But read is even more suitable: bash-4.2$ IFS=';' read -r id string <<&...


51

This wasn't available back then but with more recent versions (≥ 8.16) of gnu split one can use the --additional-suffix switch to have control over the resulting extension. From man split: --additional-suffix=SUFFIX append an additional SUFFIX to file names. so when using that option: split -dl 10000 --additional-suffix=.txt words wrd the ...


36

The easiest way is probably to use head and tail: $ head -n 1000 input-file > output1 $ tail -n +1001 input-file > output2 That will put the first 1000 lines from input-file into output1, and all lines from 1001 till the end in output2


32

Used sed for example: $ echo 'version: 1.8.0.110' | sed 's/\./-/3' version: 1.8.0-110 Explanation: sed s/search/replace/x searches for a string and replaces the second. x determines which occurence to replace - here the 3rd. Often g is used for x to mean all occurances. Here we wish to replace the dot . but this is a special character in the regular ...


29

Solved it using convert -crop geometry +repage: convert -crop 100%x20% +repage image.png image.png


29

I would use grep: $ grep -o . <<<"StackOver" S t a c k O v e r or sed: $ sed 's/./&\n/g' <<<"StackOver" S t a c k O v e r And if empty space at the end is an issue: sed 's/\B/&\n/g' <<<"StackOver" All of that assuming GNU/Linux.


27

Use awk: awk -F, '{ print > $2 ".csv" }' file.csv This will create the two files 577.csv and 132.csv in your current directory. The command above assumes that you can only have 132 or 577 as the second field. It will create one file name for each of the values found in the second field of the entire file.csv. If there are other values apart from the ...


26

Using only POSIX sh constructs, you can use parameter substitution constructs to parse one delimiter at a time. Note that this code assumes that there is the requisite number of fields, otherwise the last field is repeated. string='one_two_three_four_five' remainder="$string" first="${remainder%%_*}"; remainder="${remainder#*_}" second="${remainder%%_*}"; ...


25

Using ImageMagick: $ convert -crop 800x1000 image.png cropped_%d.png Will create a sequence of files named cropped_1.png, cropped_2.png, and so on. References Tile Cropping, sub-dividing one image into multiple images ImageMagick v6 Examples -- Cutting and Bordering


21

Wanted to see an awk answer, so here's one: A=$(awk -F_ '{print $2}' <<< 'one_two_three_four_five') B=$(awk -F_ '{print $4}' <<< 'one_two_three_four_five')


20

This is caused by the size of the field used to store the uncompressed size in gzipped files: it’s only 32 bits, so gzip can only store sizes of files up to 4 GiB. Anything larger is compressed and uncompressed correctly, but gzip -l gives an incorrect uncompressed size. So splitting the tarball and reconstructing it hasn’t caused this, and shouldn’t have ...


19

You may want to break on grapheme clusters instead of characters if the intent is to print text vertically. For instance with a e with an acute accent: With grapheme clusters (e with its acute accent would be one grapheme cluster): $ perl -CLAS -le 'for (@ARGV) {print for /\X/g}' $'Ste\u301phane' S t é p h a n e (or grep -Po '\X' with GNU grep built with ...


18

With any standard sh (including bash): sep=';' case $s in (*"$sep"*) before=${s%%"$sep"*} after=${s#*"$sep"} ;; (*) before=$s after= ;; esac read based solutions would work for single character (and with some shells, single-byte) values of $sep other than space, tab or newline and only if $s doesn't contain newline characters. ...


15

Unless I'm missing something, split does split by line if you use -l switch: -l, --lines=NUMBER put NUMBER lines per output file so split -l 1 inputfile should do what you want.


15

I think that split is you best approach. Try using the -l xxxx option, where xxxx is the number of lines you want in each file (default is 1000). You can use the -n yy option if you are more concerned about the amount of files created. Use -n 2 will split your file in only 2 parts, no matter the amount of lines in each file. You can count the amount of ...


14

Such tasks are best managed with the shell. Use split and then write a simple loop to rename the files. E.g. for file in wrd.* do mv "$file" "$file.txt" done would rename your wrd.01, wrd.02, etc. files so they all have a .txt extension.


14

Method #1 - Using head & tail You can use the command head to pull out the first 40 files from a file listing like so: $ head -40 input_files | xargs ... To get the next 40: $ tail -n +41 input_file | head -40 | xargs ... ... $ tail -n +161 input_file | head -40 | xargs ... You can keep walking down the list, 40 at a time using this same ...


14

This is a job for csplit: csplit -sf file -n 1 large_file /XYZ/ would silently split the file, creating pieces with prefix file and numbered using a single digit, e.g. file0 etc. Note that using /regex/ would split up to, but not including the line that matches regex. To split up to and including the line matching regex add a +1 offset: csplit -sf file -n ...


13

Use --pipe: cat 2011.psv | parallel --pipe -l 50000000 ./carga_postgres.sh It requires ./carga_postgres.sh to read from stdin and not from a file, and is slow for GNU Parallel version < 20130222. If you do not need exactly 50000000 lines the --block is faster: cat 2011.psv | parallel --pipe --block 500M ./carga_postgres.sh This will pass chunks of ...


13

awk 'NR==1 {n=$2} { file = sprintf("file.%.4d", ($2-n)/10000) if (file != last_file) { close(last_file) last_file = file } print > file }' Would write to file.0000, file.0001... (the number being int(($2-n)/10000) where n is $2 for the first line). Note that we close files once we've stopped ...


12

Not with split, but you can easily rename them afterwards, or you can do it in awk: awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile


12

pdftk is able to cut out a fixed set of pages efficiently. With a bit of scripting glue, this does what I want: number=$(pdfinfo -- "$file" 2> /dev/null | awk '$1 == "Pages:" {print $2}') count=$((number / pagesper)) filename=${file%.pdf} counter=0 while [ "$count" -gt "$counter" ]; do start=$((counter*pagesper + 1)); end=$((start + pagesper - 1)); ...


12

s="hello" declare -a a # define array a for ((i=0; i<${#s}; i++)); do a[$i]="${s:$i:1}"; done declare -p a # print array a in a reusable form Output: declare -a a='([0]="h" [1]="e" [2]="l" [3]="l" [4]="o")' or (please note the comments) s="hello" while read -n 1 c; do a+=($c); done <<< "$s" declare -p a Output: declare -a a='([0]="h" [...


12

The commands basename and dirname can be used for that, for example: $ basename /home/user/a/directory/myapp.app myapp.app $ dirname /home/user/a/directory/myapp.app /home/user/a/directory For more information, do not hesitate to do man basename and man dirname.


11

You can use awk for the job: $ curl -O https://raw.githubusercontent.com/qtproject/qt-mobility\ /d7f10927176b8c3603efaaceb721b00af5e8605b/demos/qmlcontacts/contents/\ example.vcf $ gawk ' /BEGIN:VCARD/ { close(fn); ++a; fn=sprintf("card_%02d.vcf", a); print "Writing: ", fn } { print $0 > fn; } ' example.vcf Writing: card_01.vcf Writing: ...


11

csplit -f vcard input.txt -z '/END:VCARD/+1' '{*}'


11

Use xargs (17 seconds): xargs -n1000 <file >output It uses the -n flag of xargs which defines the max number of arguments. Just change 1000 to 500 or whatever limit you want. I made a test file with 10^7 words: $ wc -w file 10000000 file Here are the time stats: $ time xargs -n1000 <file >output real 0m16.677s user 0m1.084s sys ...


11

The simplest way (for shells with <<<) is: IFS='_' read -r a second a fourth a <<<"$string" Using a temporal variable $a instead of $_ because one shell complains. In a full script: string='one_two_three_four_five' IFS='_' read -r a second a fourth a <<<"$string" echo "$second $fourth" No IFS changing, not issues with set -...


10

With awk you can do: awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile Explanation: The first awk argument (out=file1) defines a variable with the filename that will be used for output while the subsequent argument (largefile) is processed. The awk program will print all lines to the file specified by the variable out ({print >out}). If the ...


Only top voted, non community-wiki answers of a minimum length are eligible