How to replace "\n" in AppleScript? - macos

I want to replace "\n" in Applescript. Whenever I write that, it just brings whatever is after \n to the next line. How do I do that?
set newVar to my replaceText("\n/blah-blah", "")
EDIT:
set newVar to my replaceText(linefeed, "", newVar)
log newVar
newVar still prints with \n towards the end.

Found this solution to your problem, Go to preferences-->Editing and check Escape tabs and line breaks in strings
http://forums.macrumors.com/showthread.php?t=1395073

This should catch them all:
set oldText to "line 1
line 2
line 3"
set AppleScript's text item delimiters to {return & linefeed, return, linefeed, character id 8233, character id 8232}
set newText to text items of oldText
set AppleScript's text item delimiters to {" "}
set newText to newText as text
using "blah\n" as oldText

Use the linefeed AppleScript constant:
set newVar to my replaceText(linefeed & "/blah-blah", "")

Related

Remove characters between markers in a bash variable

I'm trying to remove unknown characters between 2 known markers from a variable using bash.
eg
string="This text d #! more text jsdlj end and mo{re ;re end text.text"
I want to remove all the characters between the last word "text " (before the end word) and the first occurance thereafter called "end" . ie between the last occurance of the word "text " after that the first occurance of the word "end", but keeping both these markers)
result="This text d #! more text end and mo{re ;re end text.text"
I'll be using it as part of a find -print0 | xargs -0 bash -c 'command; command...etc.' script.
I've tried
echo $string | sed 's/[de][ex][ft][^\-]*//' ;
but that does it from the first "ext" and "-" (not the last "ext" before the end marker) and also does not retain the markers.
Any suggestions?
EDIT: So far the outcomes are as follows:
string="text text text lk;sdf;-end end 233-end.txt"
start="text "
end="-end"
Method 1
[[ $string =~ (.*'"${start}"').*('"${end}"'.*) ]] || :
nstring="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" ;
echo "$nstring" ;
>"text text text -end.txt"
Required output = "text text text -end end 233-end.txt"
Method 2
temp=${cname%'"$end"'*}
nend=${cname#"$temp"}
nstart=${temp%'"$start"'*}
echo "$nstart$nend"
>"text text -end.txt"
Required output = "text text text -end end 233-end.txt"
Method 3
nstring=$(sed -E "s/(.*'"$start"').*('"$end"')/\1\2/" <<< "$string")
echo "$nstring";
>"text text text -end.txt"
Required output = "text text text -end end 233-end.txt"
Method 4
nstring=$(sed -En "s/(^.*'"$start"').*('"$end"'.*$)/\1\2/p" <<< "$string")
echo "$nstring" ;
>"text text text -end.txt"
Required output = "text text text -end end 233-end.txt"
Using Bash's Regex match:
#!/usr/bin/env bash
string='This text and more text jsdlj-end.text'
[[ $string =~ (.*text\ ).*(-end.*) ]] || :
printf %s\\n "${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
UPDATE: question has been updated with more details for dealing with a string that contains multiple start and end markers.
The new input string:
This text d #! more text jsdlj end and mo{re ;re end text.text
Test case:
start marker = 'text'
end marker = 'end'
objective = remove all text between last start marker and before the first end marker (actually replace all said text with a single space)
Input with all markers in bold:
This text d #! more text jsdlj end and mo{re ;re end text.text
Input with the two markers of interest in bold:
This text d #! more text jsdlj end and mo{re ;re end text.text
Desired result:
This text d #! more text end and mo{re ;re end text.text
While we can use sed to remove the desired text (replace <space>jsdlj<space> with <space>), we have to deal with the fact that sed does greedy matching (fine for finding the 'last' start marker) but does not do non-greedy matching (needed to find the 'first' end marker). We can get around this limitation by switching out our end marker with a single-character replacement, simulate a non-greedy match, then switch back to the original end marker.
m1='text' # start marker
m2='end' # end marker
string="This text d #! more text jsdlj end and mo{re ;re end text.text"
sed -E "s/${m2}/#/g;s/(^.*${m1})[^#]*(#.*$)/\1 \2/;s/#/${m2}/g" <<< "${string}"
Where:
-E - enable Extended regex support (includes capture groups)
s/${m2}/#/g - replace our end marker with the single character # (OP needs to determine what character cannot show up in expected input strings)
(^.*${m1}) - 1st capture group; greedy match from start of string up to last start marker before ...
[^#]* - match everything that's not the # character
(#.*$) - 2nd capture group; everything from # character until end of string
\1 \2 - replace entire string with 1st capture group + <space> + 2nd capture group
s/#/${m2}/g - replace single character # with our end marker
This generates:
This text d #! more text end and mo{re ;re end text.text
Personally, I'd probably opt for a more straight forward parameter expansion approach (similiar to Jetchisel's answer) but that could be a bit problematic for inline xargs processing ... ???
Original answer
One sed idea using capture groups:
$ string="This text and more text jsdlj-end.text"
$ sed -En 's/(^.*text ).*(-end.*$)/\1\2/p' <<< "${string}"
This text and more text -end.text
Where:
-En - enable Extended regex support (and capture groups) and (-n) disable default printing of pattern space
(^.*text ) - first capture group = start of line up to last text
.* - everything between the 2 capture groups
(-end.*$) - second capture group = from -end to end of string
\1\2/p - print the contents of the 2 capture groups.
Though this runs into issues if there are multiple -end strings on the 'end' of the string, eg:
$ string="This text and more text jsdlj-end -end.text"
$ sed -En 's/(^.*text ).*(-end.*$)/\1\2/p' <<< "${string}"
This text and more text -end.text
Whether this is correct or not depends on the desired output (and assuming this type of 'double' ending string is possible).
With Parameter Expansion.
string="This text and more text jsdlj-end.text"
temp=${string%-*}
end=${string#"$temp"}
start=${temp% *}
echo "$start$end"
This is a bit tricky using only a posix extended regex (ERE), but easy with a perl compatible regex (PCRE). Therefore, we switch from sed to perl:
To get the last text (that still has a end afterwards), put a .* in front. The closest end to that text can then be matched using a non-greedy .*?.
Here we also put \b around text and end to avoid matching parts of other words (for example, the word send should not be matched even though it contains end too).
perl -pe 's/(.*\btext\b).*?(\bend\b)/\1 \2/' <<< "$string"

How to write this apple script

I want to write an apple script that if it sees a json of a very certain format, it copies to the clipboard all the individual lines with the keys and all the individual values without the keys
For example
{
"stam": "value1",
"stam1": "value2",
"stam2": "value3"
}
I want the lines to be copied to the clipboard the following way:
I mostly want it to go on my clipboard history, each line on its own
"stam": "value1",
value1
"stam1": "value2",
value2
"stam2": "value3",
value3
Is it possible to do it?
As there don't seem to be any takers for an Applescript version after 2 days, I'll offer a shell method which you are welcome to ignore if it's not for you.
So, if you copy your JSON into your Clipboard and run the following in the Terminal, it should do what you ask:
pbpaste | awk -F':' '/:/ {gsub(/ /,""); print; gsub(/"/, "", $2); print $2}'
That pastes the Clipboard into awk (which is included in every macOS) and tells it to treat the colon (:) as the field separator. It then looks for and processes only lines containing colons as follows. It removes all spaces and prints the line. Then it removes all double quotes (") from the second field on the line and prints the result on a new line.
So, if you make a script called $HOME/go containing the following, it will write the result back onto your Clipboard:
#!/bin/bash
pbpaste | awk -F':' '/:/{gsub(/ /,"");print; gsub(/"/, "", $2); print $2}' | pbcopy
You can then make it executable (only necessary one time) with:
chmod +x $HOME/go
Then you can execute it from Applescript with:
do shell script "/Users/YOU/go"
Or, if you insist on Applescript you can do something ugly like this:
set lns to paragraphs of (the clipboard as text)
set res to ""
repeat with ln in lns
if (ln contains ":") then
set res to (res & ln & "\n") as string
set AppleScript's text item delimiters to ":"
set fields to every text item of ln
set AppleScript's text item delimiters to ""
set val to (item 2 of fields)
set res to (res & val & "\n") as string
end if
end repeat
display dialog res

How to remove last space text clipboard applescript?

It was:
"hello
hello
hello
"
need
"hello hello hello"
If last characters space to remove
Thank all!
get the clipboard
set the clipboard to (replacement of "1" by "2" for the result)
on replacement of oldDelim by newDelim for sourceString
set oldTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to oldDelim
set strtoks to text items of sourceString
set text item delimiters of AppleScript to newDelim
set joinedString to strtoks as string
set text item delimiters of AppleScript to oldTIDs
joinedString
end replacement
set the clipboard to "hello hello hello "
set theString to get the clipboard
set theWords to text from first word to last word of theString
set the clipboard to quote & theWords & quote
RETURNS:
"hello hello hello" -- with quotes
If you do not want quotes
set the clipboard to "hello hello hello "
set theString to get the clipboard
set theWords to text from first word to last word of theString
set the clipboard to theWords
RETURNS:
hello hello hello -- without quotes
Assuming the clipboard only contains a single line of text as in your question e.g. "hello hello hello ", without the quotes, the following one liner removes the trailing space.
set the clipboard to text from first word to last word of (the clipboard as text)
Note: This also removes any amount leading and trailing whitespace and is unlimited in the number of words of text the single line of text on the clipboard contains.
Here's a concise method that compares the last character to a list of white space. Cleaner than a series of if or's.
-- set clipboard to "hello hello hello "
set theString to the clipboard
repeat 99 times
set c to last character of theString
if c is in {tab, space, return} then
set theString to text 1 thru -2 of theString
else
exit repeat
end if
end repeat
return theString
(it's technically faster to grab "text -2 thru -1 of theString" instead of "last character", however that will ignore trailing return characters so won't work for you)

Store the word of a string in a file.txt into a variable AppleScript

I have a file.txt which is composed by some string each one is structured like this:
word1 word2 word3
I would like to write a script which allows me to find the string which start with "word1" and get the content of "word2" and "word3" into two variables.
Something like this
set searchTerm to "foo"
set variable1 to ""
set variable2 to ""
set theText to paragraphs of (read (choose file))
repeat with aLine in theText
set theWords to words of aLine
if item 1 of theWords is searchTerm and ((count theWords) > 3) then
set variable1 to item 2 of theWords
set variable2 to item 3 of theWords
exit repeat
end if
end repeat

How to Indent a String in Bash using printf?

Is there an example of indenting strings in Bash (for output)?
I found examples using printf but they don't seem to work as expected.
I want to simply indent a given string with a given number of spaces.
echo "Header"
indent "Item 1" 2
indent "Sub Item 1a" 4
indent "Sub Item 1b" 4
would produce the output
Header
Item 1
Sub Item 1a
Sub Item 1b
In printf, something like %3s means "a string, but with as many initial spaces as are necessary to ensure that the string is at least 3 columns wide".
This works even if the string is the empty string '', in which case %3s means essentially "three spaces".
So, for example, indent "Sub Item 1a" 4 can be expressed as printf '%4s%s\n' '' "Sub Item 1a", which prints four spaces followed by "Sub Item 1a" and a newline.
If you want, you can implement indent as a function:
function indent () {
local string="$1"
local num_spaces="$2"
printf "%${num_spaces}s%s\n" '' "$string"
}

Resources