I have a text file that looks something similar to this:
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here
Now the problem is some lines does this:
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here or even
longer like this
Now I have lines that vary in length, and do things like the above examples. My goal is I need every single line to look like the first example. IE I want every line to begin with the "+PhoneNumber" not text. All of the text should be backspaced up to it's previous line so it finishes the sentence. So it would be more like this:
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here or even longer like this
I am completely at a loss at how to get a script or anything to do this for me, so I'm asking for assistance. I've tried googling it and nothing is of any assistance. For now I am editing every line by hand, but there are over 30000 lines of text, and to edit all that by hand would take forever. So any assistance would be GREATLY appreciated. Thanks guys!
TLDR; Need a script that will back text up to the previous line if the line it is on doesn't start with a +
i suggest to use two expression first replace \r\n with space and then (.*?)+ replace with $1\r\n+
in notepad++ for quick output
Assuming you have access to awk:
~ $ cat test.awk
/^\+/ { printf "\n%s", $0; }
/^[^+]/ { printf " %s", $0; }
END { print ""; }
~ $ cat test.input
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
but runs down to here or even
longer like this
~ $ awk -f test.awk <test.input | tail +2
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here
+PhoneNumber 3/5/15 7:16 PM us Text is here but runs down to here or even longer like this
Related
I would like to convert the human readable date into YYYYMMDD. Just wondering how can I do this. Thanks.
Input Date :-
Sep 30, 2016 11:20:34 AM
Output Date :-
20160930112034
5 (Friday)
This command will have exact output you have posted at Ubuntu 16.04:
$ date -d"Sep 30, 2016 11:20:34 AM" "+%Y%m%d%H%M%S %n%u (%A)"
20160930112034
5 (Friday)
According to this question you might need to adjust it for Mac os.
Check this command for ex.:
$ date -j -vJulm -v20d -v1999y '+%A'
Here is manual for date command for Mac OS X.
Here is a Bash solution:
$ date -d"Sep 30, 2016 11:20:34 AM" "+%Y%m%d - %A"
20160930 - Friday
I need to remove only lines (in text file) ending with a number.
Before:
1987 Robocop
1990 Robocop 2
1993 Robocop 3
2014 Robocop
After:
1987 Robocop
2014 Robocop
Since you're referencing my favorite movie, I'll answer:
sed '/[ \t][0-9][0-9]*[ \t]*$/d' movies.txt
Which translates to:
Delete any line where there is either a space or a tab, followed by at least one digit, then any amount of spaces or tabs at the end of a line.
There are more compact ways to represent this on Linux, but I gave you one that does it the hard way for portability's sake.
With GNU sed:
sed '/[0-9]$/d' file
If you want to edit "in place" add option -i.
in linux ,bash program.
I write this:
msg=`date '+%m-%d %H:%M'`" alipay recharge [$sum] in past 15 mins"
echo $msg >> $MonitorLog
Mostly it works ,but sometime.the result will like this:
07-15 09:01 card recharge 0 in past 30 mins
My sentence changes. not 0, if $sum=0 ,it should be:
07-15 09:01 card recharge [0] in past 30 mins
I don't know where my '[]' is? can you help me ,thanks a lot.
You are hitting shell globbing. See the output below.
$ ls -l
total 4
-rw-r--r-- 1 root root 0 Jul 14 21:40 5
$ sum=10
$ msg=`date '+%m-%d %H:%M'`" alipay recharge [$sum] in past 15 mins"
$ echo $msg
07-14 21:41 alipay recharge [10] in past 15 mins
$ sum=5
$ msg=`date '+%m-%d %H:%M'`" alipay recharge [$sum] in past 15 mins"
$ echo $msg
07-14 21:41 alipay recharge 5 in past 15 mins
$ echo "$msg"
07-14 21:41 alipay recharge [5] in past 15 mins
#Etan Reisinger's answer contains the crucial pointer:
Shell expansions are inadvertently applied to $msg, because it is unquoted.
tl;dr:
Double-quote your variable references to protect them from interpretation by the shell:
echo "$msg" >> "$MonitorLog" # due to double-quoting, contents of $msg used as is
Generally, the only reason NOT to double-quote a variable reference is the express intent to have the shell interpret the value (apply expansions to it) - see below.
In the case at hand, here's what happens if you do not double-quote $msg:
After splitting the value of $msg into words by whitespace (word splitting), pathname expansion is applied to each:
I.e., each word that looks like a glob (a filename pattern), is matched against filenames - in the specified directory or, without a path component, in the current one - and if matches are found, that word is replaced by matching filenames.
A word such as [0] happens to be a valid glob ([...] encloses a set of matching characters; in this case, the set is made up of only 1 char., 0), and if a file named 0 happens to be present in the current directory, [0] is replaced by that matching filename, 0 - effectively making the [] disappear - this is what happened in the OP's case.
(See man bash, section Pathname Expansion, for what constitutes valid globs.)
Linux v2.4/Bash v3.2/GNU utils/date command version 5.0
I'm struggling with the date command. In a BASH application, the user can set date and time separately, resulting in separate variables for date and time. Further on, these variables are re-combined but this appears not be palatable for the date command: I get a different date back. Time is the same, however. Testing code:
#!/bin/bash
dnow1="$(date)"
echo "1 $dnow1" # --> Sat Sep 14 16:31:48 EDT 2013
#split date and time
dldate="$(date -d "$dnow1" +"%d-%m-%Y")"
echo "2 $dldate" # --> 14-09-2013
dltime="$(date -d "$dnow1" +"%H:%M:%S")"
echo "3 $dltime" # --> 16:31:48
#try to re-combine date and time
string="${dldate} ${dltime}"
echo "4 $string" # --> 14-09-2013 16:31:48
dnow2="$(date -d "$string")"
echo "5 $dnow2" # --> Thu Mar 5 16:31:48 EST 2020
I must be missing something here. Can anyone enlighten me? Thanks!
Note:
I'm working an original XBOX that has few/low resources so there's no room for other solutions like Python. I'm a 'bashist' anyway so it must be BASH!
Edit: corrected time format. Thanks Mat.
As to "$(....)" I have made it a habit to double quote wherever possible.
When getting your date use this format instead:
#split date and time
dldate="$(date -d "$dnow1" +"%Y-%m-%d")"
From GNU date manual
The output of the date command is not always acceptable as a date string, not only because of the language problem, but also because there is no standard meaning for time zone items like ‘IST’. When using date to generate a date string intended to be parsed later, specify a date format that is independent of language and that does not use time zone items other than ‘UTC’ and ‘Z’.
First of all using -d won't work in 14-09-2013 fashion, you can easily set date and time with one command and put it into variable. eg, just try this below on shell and then you can put into shell script.
date --date="Feb 2 2014 13:12:10"
Sun Feb 2 13:12:10 PST 2014
I need something simple like date, but in seconds since 1970 instead of the current date, hours, minutes, and seconds.
date doesn't seem to offer that option. Is there an easy way?
This should work:
date +%s
Just to add.
Get the seconds since epoch(Jan 1 1970) for any given date(e.g Oct 21 1973).
date -d "Oct 21 1973" +%s
Convert the number of seconds back to date
date --date #120024000
The command date is pretty versatile. Another cool thing you can do with date(shamelessly copied from date --help).
Show the local time for 9AM next Friday on the west coast of the US
date --date='TZ="America/Los_Angeles" 09:00 next Fri'
Better yet, take some time to read the man page
http://man7.org/linux/man-pages/man1/date.1.html
Pure bash solution
Since bash 5.0 (released on 7 Jan 2019) you can use the built-in variable EPOCHSECONDS.
$ echo $EPOCHSECONDS
1547624774
There is also EPOCHREALTIME which includes fractions of seconds.
$ echo $EPOCHREALTIME
1547624774.371210
EPOCHREALTIME can be converted to micro-seconds (μs) by removing the decimal point. This might be of interest when using bash's built-in arithmetic (( expression )) which can only handle integers.
$ echo ${EPOCHREALTIME/./}
1547624774371210
In all examples from above the printed time values are equal for better readability. In reality the time values would differ since each command takes a small amount of time to be executed.
So far, all the answers use the external program date.
Since Bash 4.2, printf has a new modifier %(dateformat)T that, when used with argument -1 outputs the current date with format given by dateformat, handled by strftime(3) (man 3 strftime for informations about the formats).
So, for a pure Bash solution:
printf '%(%s)T\n' -1
or if you need to store the result in a variable var:
printf -v var '%(%s)T' -1
No external programs and no subshells!
Since Bash 4.3, it's even possible to not specify the -1:
printf -v var '%(%s)T'
(but it might be wiser to always give the argument -1 nonetheless).
If you use -2 as argument instead of -1, Bash will use the time the shell was started instead of the current date. This can be used to compute elapsed times
$ printf -v beg '%(%s)T\n' -2
$ printf -v now '%(%s)T\n' -1
$ echo beg=$beg now=$now elapsed=$((now-beg))
beg=1583949610 now=1583953032 elapsed=3422
With most Awk implementations:
awk 'BEGIN {srand(); print srand()}'
This is an extension to what #pellucide has done, but for Macs:
To determine the number of seconds since epoch (Jan 1 1970) for any given date (e.g. Oct 21 1973)
$ date -j -f "%b %d %Y %T" "Oct 21 1973 00:00:00" "+%s"
120034800
Please note, that for completeness, I have added the time part to the format. The reason being is that date will take whatever date part you gave it and add the current time to the value provided. For example, if you execute the above command at 4:19PM, without the '00:00:00' part, it will add the time automatically. Such that "Oct 21 1973" will be parsed as "Oct 21 1973 16:19:00". That may not be what you want.
To convert your timestamp back to a date:
$ date -j -r 120034800
Sun Oct 21 00:00:00 PDT 1973
Apple's man page for the date implementation:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/date.1.html
use this bash script (my ~/bin/epoch):
#!/bin/bash
# get seconds since epoch
test "x$1" == x && date +%s && exit 0
# or convert epoch seconds to date format (see "man date" for options)
EPOCH="$1"
shift
date -d #"$EPOCH" "$#"